sta*_*tiv 6 c++ gcc clang sfinae
我正在学习如何使用SFINAE.我正在尝试使用它来根据serialize()
对象中函数的存在来选择函数实现.
这是我用来确定的代码,如果类型定义了serialize()函数:
template <typename T>
class HasSerialize {
private:
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
template <typename C> static no& test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
Run Code Online (Sandbox Code Playgroud)
但是,它似乎在GCC和Clang上给出了完全相同的结果.假设以下代码:
template<bool T>
class NVPtypeSerializer {
public:
template<typename C>
static xmlChar* serialize(C value) {
// serize() is not available
}
};
template<>
struct NVPtypeSerializer<true> {
public:
template<typename T>
static xmlChar* serialize(T value) {
return value.serialize();
}
};
Run Code Online (Sandbox Code Playgroud)
这被称为:
foo = NVPtypeSerializer<HasSerialize<Bar>::value >::serialize(value);
Run Code Online (Sandbox Code Playgroud)
哪个班级Bar
没有这个serialize()
功能.这段代码在Clang 3.1下编译得很好,但是在GCC 4.7.1上我得到以下错误:
error: ‘class Bar’ has no member named ‘serialize’
Run Code Online (Sandbox Code Playgroud)
如果我更改struct NVPtypeSerializer<true>
为struct NVPtypeSerializer<false>
它可以在GCC上编译,但Clang给出以下错误:
error: no member named 'serialize' in 'Bar'
Run Code Online (Sandbox Code Playgroud)
问题出在哪儿?它在我的代码中吗?我希望尽可能地使代码具有可移植性.
这真的是代码吗test(char[sizeof(&C::serialize)])
?请注意,采用数组的函数声明实际上声明了采用指针的函数:
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
Run Code Online (Sandbox Code Playgroud)
这实际上意味着:
template <typename C> static yes& test( char* );
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这就是使您的调用test<C>(0)
编译的原因。我认为这不是检测该函数是否存在的正确方法。谷歌如何使用 SFINAE 检测类中是否存在成员/成员函数。
(一个简单的解决方案是添加一个额外的默认参数——前提是您有一个启用了 C++11 的编译器:
template <typename C, std::size_t = sizeof(&C::serialize)>
static yes& test(int) ;
Run Code Online (Sandbox Code Playgroud)
)
归档时间: |
|
查看次数: |
407 次 |
最近记录: |