2013-08-30 55 views
1
template<class T> 
struct is_class_or_union 
{ 
    struct twochar { char _[2]; }; 
    template <class U> 
    static char is_class_or_union_tester(void(U::*)(void)); 
    template <class U> 
    static twochar is_class_or_union_tester(...); 
    static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); 
}; 

上述代码来自boost库的meta_utils.hppBoost代码摘录 - 无法理解

  1. is_class_or_union_tester似乎是一个static函数返回char并采取指针成员函数(返回void并接受无)。没有功能体,它似乎没有在其他地方定义。我不明白它是如何工作的,而且最重要的是,我不明白该功能的用途。
  2. 我不明白以下代码的概念: static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); sizeof运算符应用于什么?他们想在这里找到什么?
+0

[C++ SFINAE示例?]的可能的重复(http://stackoverflow.com/questions/982808/c-sfinae-examples) – soon

+0

@peter感谢您的解释。它当然有帮助。我不知道没有链接器错误(对于函数定义),因为该函数从未被调用? –

+0

没有链接器错误,因为实际上没有创建代码。 'sizeof'实际上并不执行它传递的表达式,而是计算出结果的类型,然后计算它的大小。 –

回答

3

这里采用的技术是SFINAE(替换失败不是错误),这是编译器用来选择可能的候选模板之间的匹配的一种技术,特别是在模板参数的无效替换本身不在其中在匹配过程中出现错误。在这种情况下,编译器试图找到一个匹配:

is_class_or_union_tester<T>(0) 

它可以选择

template <class U> 
static char is_class_or_union_tester(void(U::*)(void)); 

template <class U> 
static twochar is_class_or_union_tester(...); 

之间。如果T是一个类会选择第一个功能因为一个类可以有一个成员函数。如果T是工会,它将选择第二个。回想一下,sizeof不会执行这些函数,只会对模板声明中的返回类型起作用。你会看到返回类型是不同的,这使得与sizeof(char)的比较返回正确的值。

+0

让我想知道,如果语言允许并且人们使用这种机制,那么应该设计一个明确的方法来实现这一点。这看起来非常非常黑客。 – szpanczyk