Есть ли способ для определения типа для аргументов функции шаблона? - PullRequest
0 голосов
/ 10 июня 2018

Приведенный ниже код должен показать, что я имею в виду, можно ли использовать шаблонную функцию typedef в аргументах ...

#include <vector>

struct vec2
{
    float x, y;
};
struct dvec2
{
    double x, y;
};

template <typename T>
void function(std::vector<T>& list, decltype(T::x) scalarVal, decltype(T::x) scalarVal2)
{

    typedef decltype(T::x) scalarType;
    scalarType a; // a is now a double or float depending on template argument
}

int main() 
{
    std::vector<vec2> vecOfVec2;
    std::vector<dvec2> vecOfDvec2;
    function(vecOfVec2, 0.f, 1.f);
    function(vecOfDvec2, 0.0, 1.0);

}

Итак, вы можете видеть, что в функции, которую я сделал, typedef из:

typedef decltype(T::x) scalarType;

А затем используйте scalarType для обозначения либо float, либо double.Было бы полезно, если бы я мог перечислить аргументы функции функции следующим образом:

void function(std::vector<T>& list, scalarType scalarVal, scalarType scalarVal2)

, но, видя, что typedef не создается, пока внутри функции это не будет работать.Если это невозможно, допустимо ли это сделать:

(decltype(T::x) scalarVal, ...)

для аргументов каждый раз, как я это показал в примере?

1 Ответ

0 голосов
/ 10 июня 2018

А затем используйте «scalarType», чтобы обозначить как float или double.Было бы полезно, если бы я мог перечислить аргументы функции функции следующим образом:

Это не может работать, поскольку скалярный тип зависит от типа вектора.Как вы можете узнать, какой тип является правильным, если вы пропустите там зависимость типа?В любом случае, вы должны указать где-нибудь, какой тип вектора вы используете.

Если это невозможно, допустимо ли это сделать:

(decltype(T::x) scalarVal, ...)

для аргументов каждый раз, когда япоказали это в примере?

Есть лучшие варианты.Таким образом, вы делаете интерфейс функции зависимым от внутреннего представления данных, что не является рекомендательным.Реализации могут отличаться, реализации могут изменяться, и прерывание изменений сделает интерфейс таким образом недействительным.Кроме того, если кто-то еще работает с вашим кодом, не зная его внутренних компонентов, он / она должен будет на самом деле проверить детали реализации, чтобы выяснить, что вы на самом деле имеете в виду.Вместо этого вы можете просто определить общее имя внутри каждого вектора, например

struct dvec {
    using scalarType = double;
    ...
};

struct vec2 {
    using scalarType = float;
    ...
};

template <typename T>
void foo(typename T::scalarType bar) { ... }

. Это очень распространенный шаблон, используемый в STL.

...