我正在为嵌入式设备开发应用程序,因此我没有type_traits
和enable_if
(编译器质量差)。我自己创建了它们:
template <typename T>
struct is_pointer_t{
enum{value = false};
};
template <typename T>
struct is_pointer_t<T*>{
enum{value = true};
};
和consts
和volatiles
的simillar声明。
现在实施enable_if
:
template <bool boolean, typename T = void>
struct enable_if{};
template <typename T>
struct enable_if<true, T>{
typedef T type;
};
现在我想要一个类,依赖于我使用指针或普通类型它会在它们上面调用析构函数,所以如果我可以使用模板化的析构函数,那将会很棒。但我不知道如何做到这一点,因为我刚刚开始解决模板编程问题。以下尝试失败:
template <typename T>
class pointerOrNot{
public:
template <typename U>
void one();
};
template <typename T>
template <typename enable_if<is_pointer_t<T>::value>::type>
void pointerOrNot<T>::one(){
std::cout << "Success1" << std::endl;
}
template <typename T>
template <typename enable_if<!is_pointer_t<T>::value>::type>
void pointerOrNot<T>::one(){
std::cout << "Success2" << std::endl;
}
它说它与定义不符。所以我试着跟随:
template <typename T>
class pointerOrNot{
public:
template <typename enable_if<is_pointer_t<T>::value>::type>
void one();
template <typename enable_if<!is_pointer_t<T>::value>::type>
void one();
};
但是其中一个()的空类型为模板,编译失败。我怎样才能做到这一点?也可以用析构函数做到这一点吗?
答案 0 :(得分:1)
首先让我们考虑以下类指针:
template <typename T>
struct Introducer{
void intro(){
std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
}
T mem;
Introducer(T m):mem(m){}
};
它可以正常使用指针,但它也适用于非指针:
Introducer<int> i(10);
i.intro();//just fine!
我们希望在编译期间检测到这种误用,我们也将导入器更改为
template <typename T>
struct Introducer{
typename enable_if<is_pointer_t<T>::value, void>::type //this is the return type of the function
intro(){
std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
}
...
};
现在编译器不允许我们使用非指针与Introducer。在下一步中,我们希望通过SFINAE为非指针设置一个特殊函数:
template <typename T>
struct Introducer{
typename enable_if<is_pointer_t<T>::value, void>::type
intro(){
std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
}
typename enable_if<!is_pointer_t<T>::value, void>::type
intro(){
std::cout<<"I'm a non-pointer, my value is "<<mem<<std::endl;
}
...
};
天哪,它甚至没有编译!让我们更仔细地阅读有关SFINAE的文章:
如果替换导致无效的类型或表达式,请键入 扣除失败。无效的类型或表达式就是一个 如果使用替换参数编写,则格式错误。只是无效 函数类型的直接上下文中的类型和表达式 及其模板参数类型可能导致演绎失败。
T
不在紧邻的情况下,因此SFINAE不起作用,让T
进入直接上下文:
template <typename T>
struct Introducer{
template <typename C=T>
typename enable_if<is_pointer_t<C>::value, void>::type
intro(){
std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
}
template <typename C=T>
typename enable_if<!is_pointer_t<C>::value, void>::type
intro(){
std::cout<<"I'm a non-pointer, my value is "<<mem<<std::endl;
}
...
};
现在的程序
int main(){
Introducer<float*> fp(NULL);
fp.intro();
//But this works also:
Introducer<int> i(10);
i.intro();
}
结果:
I'm a pointer, I point to adress 0
I'm a non-pointer, my value is 10
析构函数怎么样?最简单的方法是从析构函数中调用SFINAE-destruction-function(我从未见过SFINAE-destructor而且不知道如何编写一个,但这并不意味着什么):
template <typename T>
struct Introducer{
...
~Introducer(){
intro();
std::cout<<"and I'm deleted..."<<std::endl;
}
};