mxm*_*nkn 5 c++ templates c++11
我有这样的代码:
template< class T >
struct Value
{
/* quite a lot of other functions which I do not want to specialize, too */
void print( void );
};
template<> void Value< short int >::print() { std::cout << "is integral" << std::endl; }
template<> void Value< int >::print() { std::cout << "is integral" << std::endl; }
template<> void Value< long int >::print() { std::cout << "is integral" << std::endl; }
template<> void Value< unsigned short int >::print() { std::cout << "is integral" << std::endl; }
template<> void Value< unsigned int >::print() { std::cout << "is integral" << std::endl; }
template<> void Value< unsigned long int >::print() { std::cout << "is integral" << std::endl; }
template<> void Value< float >::print() { std::cout << "is floating point" << std::endl; }
template<> void Value< double >::print() { std::cout << "is floating point" << std::endl; }
template<> void Value< long double >::print() { std::cout << "is floating point" << std::endl; }
template< class T > void Value<T>::print() { std::cout << "unsupported type" << std::endl; }
int main( void )
{
Value< float >().print();
Value< double >().print();
Value< short >().print();
Value< char >().print();
}
Run Code Online (Sandbox Code Playgroud)
输出:
is floating point
is floating point
is integral
unsupported type
Run Code Online (Sandbox Code Playgroud)
我想改变这一点以减少代码重复,特别是因为代码体比简单的std::cout. 为了说明我想要的方向,想到的最简单的想法是使用宏:
#define TMP(T) \
template<> void Value<T>::print() { std::cout << "is integral" << std::endl; }
TMP( short int )
TMP( int )
TMP( long int )
TMP( unsigned short int )
TMP( unsigned int )
TMP( unsigned long int )
#undef TMP
#define TMP(T) \
template<> void Value<T>::print() { std::cout << "is floating point" << std::endl; }
TMP( float )
TMP( double )
TMP( long double )
#undef TMP
Run Code Online (Sandbox Code Playgroud)
但我想使用 C++11 模板魔法让它工作。我已经尝试使用std::enable_if,但我无法让它工作。比如这个
template< class T >
void Value<
typename std::enable_if< std::is_integral<T>::value, T >::type
>::print( void )
{
std::cout << "is integral" << std::endl;;
}
Run Code Online (Sandbox Code Playgroud)
给我
test.cpp:26:24: error: invalid use of incomplete type ‘struct Value<typename std::enable_if<std::is_integral<_Tp>::value, T>::type>’
>::type >::print( void )
^
test.cpp:14:8: error: declaration of ‘struct Value<typename std::enable_if<std::is_integral<_Tp>::value, T>::type>’
struct Value
Run Code Online (Sandbox Code Playgroud)
并std::enable_if在返回类型上使用:
template< class T >
typename std::enable_if< std::is_integral<T>::value, void >::type
Value<T>::print( void )
{
std::cout << "is integral" << std::endl;;
}
Run Code Online (Sandbox Code Playgroud)
给我:
test.cpp:41:1: error: prototype for ‘typename std::enable_if<std::is_integral<_Tp>::value, void>::type Value<T>::print()’ does not match any in class ‘Value<T>’
Value<T>::print( void )
^
test.cpp:16:17: error: candidate is: static void Value<T>::print()
static void print( void );
Run Code Online (Sandbox Code Playgroud)
当然已经有很多类似的问题了:
但它们通常是关于简单的函数,而不是模板类的方法。此外,他们通常不会像我想要的那样严格分开声明和定义。
这个问题听起来非常相似,但它专门针对结构/类模板参数而不是另一个模板参数的方法。
由于上述错误,我似乎无法将答案应用于我的特定问题。此外,我不想专门化整个类,因为类本身共享许多对于所有类型 T 都相同的方法。我不想将一个复制粘贴代码换成另一个。
解释为什么会出现两条错误消息的奖励。我违反了什么规则。对我来说,似乎...::type根本没有用Tor代替void。
要允许您的结构使用 SFINAE,您必须添加额外的参数:
template<class T, typename AlwaysVoid = void>
struct Value;
Run Code Online (Sandbox Code Playgroud)
进而
template<class T>
struct Value<T, std::enable_if_t<std::is_integral<T>::value>>
{
void print()
{
std::cout << "is integral" << std::endl;;
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1203 次 |
| 最近记录: |