2016-02-24 4 views
0

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

template <typename T, typename R = float, 
    typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>, 
    typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>> 
constexpr R dot(const T a_vector, const T b_vector) 
{ 
    return a_vector.x * b_vector.x + a_vector.y * b_vector.y; 
} 

Я хочу, чтобы мои пользователи также легко использовать функцию dot возвращает double вместо значения по умолчанию float. Вот почему я использую using для «typedef» dot().

template<typename T, typename R, typename ... > 
using dotd = dot<T, double>; 

Этот код дает

  • в г ++ error: ‘dot<T, float>’ does not name a type
  • в звоном ++ error: expected a type и error: expected ';' after alias declaration

Есть ли у меня возможность использовать в alternat ive для функций?

+2

Тип псевдонима может быть создан только для __types__. Функция не является типом. –

+1

@ Данди, да, да! :) Посмотрите на мой ответ. – SergeyA

+2

Вы еще не используете 'R' ... Вы имели в виду использовать' constexpr R dot (...) '? –

ответ

3

Вы можете просто перевернуть порядок аргументов шаблона. Если вы размещаете R первый, это легко для пользователя, чтобы просто указать другой тип для него, если это то, что они хотят:

template < 
    typename R = float, 
    typename T, 
    typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>, 
    typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>> 
constexpr R dot(const T a_vector, const T b_vector) 
{ 
    return a_vector.x * b_vector.x + a_vector.y * b_vector.y; 
} 

dot(a, b) А потом дает вам float против dot<double>(a, b) дает вам double. Я нахожу dot<double> намного понятнее, чем искать то, что означает dotd.

Хотя, если вы используете C++ 14, лучше просто полностью отбросить аргумент шаблона R и вернуть auto.

+0

Да, я знаю об этом. Я просто подумал, что могу укоротить его дальше до точки(). – sjaustirni

+0

Проблема с авто является, она не обрабатывает все типы изящно. Скажем, переданные векторы имеют тип int. В этом случае функция dot() не вернет никакого значимого значения. – sjaustirni

+1

@Dundee Почему тип возврата не имеет смысла? Если '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Как это хуже, чем «плавать»? – Barry

-1

Ответ очень прост:

template <class T1, class T2> void foo(); 

template <class T1, class T2> struct FooHelper { 
    static constexpr auto foo = &foo<T1, T2>; 
}; 

template <class T> 
auto food = FooHelper<T, float>::foo; 

void g() { 
    food<float>(); 
} 
+1

Почему бы не шаблон переменной? –

+0

@PiotrSkotnicki, потому что OP нужна определенная функция, а не шаблонное семейство этого. (Если я не понял вопрос). – SergeyA

+2

то почему бы и нет 'auto food = & foo ;'? –

Смежные вопросы