非模板方法的条件模板特化 class
Conditional template specialization on method of a non template class
我正在尝试使用 boost::enable_if 有条件地专门化非模板 class 的方法,但失败了。
//OSSpecific.h
...
//If some OS
typedef unsigned int UINT;
//else
typedef unsigned long long UINT;
...
//Foo.h
...
#include <OSSpecific.h>
...
class Foo
{
public:
...
template <typename T>
returnThis<T>* bar();
}
/******************************************************************/
//Foo.cpp
...
template<>
returnThis<float>* bar()
{
}
//Use this if some condition is true
template<>
returnThis<int>* Foo::bar<boost::disable_if_c<boost::is_same<int, UINT>::value >::type>()
{
//Do something
}
//Use this if some condition is true
template<>
returnThis<long long>* Foo::bar<boost::disable_if_c<boost::is_same<long long, UINT>::value >::type>()
{
//Do something
}
我收到以下错误:
Foo.cpp : error C2785: 'returnType<T> *Foo::bar(void)' and 'returnType<T> *Foo::bar(void)' have different return types
with
[
T=int
]
Foo.h : see declaration of 'Foo::bar'
Foo.cpp : see declaration of 'Foo::bar'
Foo.cpp : error C2910: 'Foo::bar' : cannot be explicitly specialized
我哪里出错了?
编辑:我试图过分简化我的问题。添加更多相关细节。
您必须遵循 ODR - 一个定义规则。所以你也必须在头文件中声明你的函数。
要使用 SFINAE,您的函数需要是模板函数——不是完全专用的模板函数——而是几个不同的模板函数。
所以 - 请参阅头文件。请注意,这里有 3 个不同的函数——它们不是彼此的特化。感谢 SFINAE first 仅在 T==float
时才有效。第二和第三如果 T==UINT
- 它们之间的区别是这个条件:UINT==unsigned int
.
class Foo
{
public:
template <typename T>
typename boost::enable_if<boost::is_same<T,float>,returnThis<float>*>::type
bar();
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
bar();
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and not boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
bar();
};
然后可能的用法文件:
int main() {
Foo f;
f.bar<float>();
f.bar<UINT>();
return 0;
}
如果UINT==unsigned int
此代码将调用第一个和第二个函数。如果 UINT!=usinged int
将调用第一个和第三个函数。
然后你的源文件(Foo.cpp):
template <typename T>
typename boost::enable_if<boost::is_same<T,float>,returnThis<float>*>::type
Foo::bar()
{
cout << "bar<T==float>()\n";
return 0;
}
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
Foo::bar()
{
cout << "bar<T==UINT and UINT==usigned int>()\n";
return 0;
}
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and not boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
Foo::bar()
{
cout << "bar<T==UINT and UINT!=usigned int>()\n";
return 0;
}
由于这些函数实际上并不依赖于 T
- 您可以要求编译器通过模板显式实例化指令在您的专用 cpp 文件中生成代码:
template returnThis<float>* Foo::bar<float>();
template returnThis<UINT>* Foo::bar<UINT>();
我正在尝试使用 boost::enable_if 有条件地专门化非模板 class 的方法,但失败了。
//OSSpecific.h
...
//If some OS
typedef unsigned int UINT;
//else
typedef unsigned long long UINT;
...
//Foo.h
...
#include <OSSpecific.h>
...
class Foo
{
public:
...
template <typename T>
returnThis<T>* bar();
}
/******************************************************************/
//Foo.cpp
...
template<>
returnThis<float>* bar()
{
}
//Use this if some condition is true
template<>
returnThis<int>* Foo::bar<boost::disable_if_c<boost::is_same<int, UINT>::value >::type>()
{
//Do something
}
//Use this if some condition is true
template<>
returnThis<long long>* Foo::bar<boost::disable_if_c<boost::is_same<long long, UINT>::value >::type>()
{
//Do something
}
我收到以下错误:
Foo.cpp : error C2785: 'returnType<T> *Foo::bar(void)' and 'returnType<T> *Foo::bar(void)' have different return types
with
[
T=int
]
Foo.h : see declaration of 'Foo::bar'
Foo.cpp : see declaration of 'Foo::bar'
Foo.cpp : error C2910: 'Foo::bar' : cannot be explicitly specialized
我哪里出错了?
编辑:我试图过分简化我的问题。添加更多相关细节。
您必须遵循 ODR - 一个定义规则。所以你也必须在头文件中声明你的函数。
要使用 SFINAE,您的函数需要是模板函数——不是完全专用的模板函数——而是几个不同的模板函数。
所以 - 请参阅头文件。请注意,这里有 3 个不同的函数——它们不是彼此的特化。感谢 SFINAE first 仅在 T==float
时才有效。第二和第三如果 T==UINT
- 它们之间的区别是这个条件:UINT==unsigned int
.
class Foo
{
public:
template <typename T>
typename boost::enable_if<boost::is_same<T,float>,returnThis<float>*>::type
bar();
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
bar();
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and not boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
bar();
};
然后可能的用法文件:
int main() {
Foo f;
f.bar<float>();
f.bar<UINT>();
return 0;
}
如果UINT==unsigned int
此代码将调用第一个和第二个函数。如果 UINT!=usinged int
将调用第一个和第三个函数。
然后你的源文件(Foo.cpp):
template <typename T>
typename boost::enable_if<boost::is_same<T,float>,returnThis<float>*>::type
Foo::bar()
{
cout << "bar<T==float>()\n";
return 0;
}
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
Foo::bar()
{
cout << "bar<T==UINT and UINT==usigned int>()\n";
return 0;
}
template <typename T>
typename boost::enable_if_c<boost::is_same<T,UINT>::value and not boost::is_same<UINT,unsigned int>::value,
returnThis<UINT>*>::type
Foo::bar()
{
cout << "bar<T==UINT and UINT!=usigned int>()\n";
return 0;
}
由于这些函数实际上并不依赖于 T
- 您可以要求编译器通过模板显式实例化指令在您的专用 cpp 文件中生成代码:
template returnThis<float>* Foo::bar<float>();
template returnThis<UINT>* Foo::bar<UINT>();