Luc*_*jer 24 c++ templates type-traits
我有一个c ++模板类,只有在模板化类型是普通旧数据时才能正常运行.任何具有执行任何操作的构造函数的东西都无法正常工作.
无论如何,当有人试图这样做时,我想以某种方式获得编译时或运行时警告.
//this should generate error
myclass<std::string> a;
//this should be fine
myclass<int> b;
Run Code Online (Sandbox Code Playgroud)
有这个诀窍吗?
Sim*_*ple 37
#include <type_traits>
template<typename T>
class myclass
{
static_assert(std::is_pod<T>::value, "T must be POD");
// stuff here...
};
Run Code Online (Sandbox Code Playgroud)
如果将非POD类型作为模板参数传递,则上述操作将导致编译错误.此解决方案需要C++ 11作为<type_traits>标头和static_assert关键字.
编辑:如果您的编译器支持TR1(大多数),您也可以在C++ 03中实现它:
#include <tr1/type_traits>
template<typename T>
class myclass
{
static char T_must_be_pod[std::tr1::is_pod<T>::value ? 1 : -1];
// stuff here...
};
Run Code Online (Sandbox Code Playgroud)
mag*_*gor 10
如果你有C++ 11支持,std :: is_pod应该完全符合你的需要.将它与std :: enable_if一起使用或与标签分配一起使用.例如这样的事情:
template <typename T, typename Enable = void>
class Test;
template<typename T>
class Test<T, typename std::enable_if<std::is_pod<T>::value, void>::type>
{};
int main() {
Test<int> t1;
//Test<std::string> t2; <-this will not compile
}
Run Code Online (Sandbox Code Playgroud)
虽然static_assert在大多数情况下可能就足够了,但使用enable_if和标签调度可以通过SFINAE的方式为您的班级用户提供更大的灵活性.考虑:
#include <type_traits>
#include <string>
#include <iostream>
template <typename T,
class=typename std::enable_if< std::is_pod<T>::value >::type>
struct myclass
{
typedef T value_type;
T data;
};
template <typename T>
void enjoy(T)
{
std::cout << "Enjoying T!" << std::endl;
}
template <typename T>
void enjoy(typename myclass<T>::value_type)
{
std::cout << "Enjoying myclass<T>::value_type!" << std::endl;
}
int main()
{
enjoy<int>(int()); // prints: Enjoying myclass<T>::value_type!
enjoy<std::string>(std::string()); // SFINAE at work - prints: enjoying T!
myclass<int> i; // compiles OK
//myclass<std::string> s; // won't compile - explicit instantiation w/non-POD!
}
Run Code Online (Sandbox Code Playgroud)
现在,如果从myclass定义中删除第二个模板参数,而不像其他人建议的那样,添加一个
static_assert(std::is_pod<T>::value, "POD expected for T");
Run Code Online (Sandbox Code Playgroud)
在类中,第二行将main()无法编译,触发static_assert.
也就是说,来自static_assert失败者的错误对人类观察者来说更加友好enable_if.所以,如果static_assert适合你,那就去吧.否则,如果您确实需要对类的泛型编程更友好,请考虑添加解释性注释enable_if:
// POD expected for T
class=typename std::enable_if< std::is_pod<T>::value >::type>
Run Code Online (Sandbox Code Playgroud)
除非你周围的人都是C++ 11流利的.
在现实生活中,解释为什么 T必须是POD static_assert以及评论文本都是一个好主意.
| 归档时间: |
|
| 查看次数: |
4947 次 |
| 最近记录: |