2015-02-20 3 views
0

У меня есть подобный кодКак определить функцию для части typenames

#include <iostream> 

struct X { 
}; 

template <typename T> 
struct A { 
    static int a(); 
}; 

template <> 
int A<int>::a() { 
    return 42; 
} 

template <> 
int A<X>::a() { 
    return 0; 
} 

int main() { 
    std::cout << A<int>().a() << std::endl; 
    std::cout << A<X>().a() << std::endl; 
    return 0; 
} 

Теперь я хочу вернуться 42 для всех типов, арифметика т.е. такие, что std::is_arithmetic<T>::type является std::true_type

Я пытался

template <typename T, typename U = std::true_type> 
struct A { 
    static int a(); 
}; 

template <typename T> 
int A<T, typename std::is_arithmetic<T>::type>::a() { 
    return 42; 
} 

Но я получил следующую ошибку:

a.cpp:12:51: error: invalid use of incomplete type ‘struct A<T, typename std::is_arithmetic<_Tp>::type>’ 
int A<T, typename std::is_arithmetic<T>::type>::a() { 
               ^
a.cpp:7:8: error: declaration of ‘struct A<T, typename std::is_arithmetic<_Tp>::type>’ 
struct A { 
     ^

, а также пытались

template <typename T> 
struct A { 
    static int a(); 
}; 

template <typename T, typename E = typename std::enable_if<std::is_arithmetic<T>::value>::type> 
int A<T>::a() { 
    return 42; 
} 

Ошибка:

a.cpp:12:13: error: default argument for template parameter for class enclosing ‘static int A<T>::a()’ 
int A<T>::a() { 
      ^
a.cpp:12:13: error: got 2 template parameters for ‘static int A<T>::a()’ 
a.cpp:12:13: error: but 1 required 

Что является правильным способом для достижения этой цели? Это вообще существует?

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

ответ

0

Нет, это не будет работать. Вместо этого попробуйте определить отдельный тип, который будет содержать либо 42, либо 0, основанный на is_arithmetic. Вы можете использовать повышение :: MPL :: if_ с целью:

template< typename T > struct Res 
{ 
    typedef typename if_< 
      std::is_arithmetic<T> 
     , static_value<42> 
     , static_value<0> 
     >::type value; 
}; 
+0

Проблема в том, что я хочу, чтобы иметь возможность добавлять другие значения для других классов – RiaD

+0

Вы можете цепи if_s столько, сколько вам нравится, или использовать другие Конструкции MPL. И поскольку «значения» являются типами, эти типы могут реализовать любую функциональность, которую вы хотите. Или вы можете просто предоставить специализированные версии самостоятельно, но тогда вам придется делать это для каждого целочисленного класса отдельно. – Andre