使用SFINAE在GCC和Clang上给出不同的结果 [英] Using SFINAE gives different results on GCC and Clang
问题描述
我正在学习如何使用SFINAE来获得我的优势。我试图使用它来选择函数实现基于 serialize()
函数在对象中的存在。
I'm learning how to use SFINAE to my advantage. I'm trying to use it to select the function implementation based on existence of a serialize()
function in an object.
这是我用来确定的代码,如果类型定义了serialize()函数:
This is the code I use to determine, if the type defines the serialize() function:
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);
};
然而,似乎给出了GCC和Clang的完全相反的结果。假设以下代码:
However, it seems to give exactly oposite results on GCC and on Clang. Assume the following code:
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();
}
};
这样调用:
foo = NVPtypeSerializer<HasSerialize<Bar>::value >::serialize(value);
Bar
serialize()
函数。这个代码编译Clang 3.1下,但是在GCC 4.7.1我得到以下错误:
Where the class Bar
doesn't have the serialize()
function. This code compiles fine under Clang 3.1, however on GCC 4.7.1 I get the following errors:
error: ‘class Bar’ has no member named ‘serialize’
如果我更改了 struct NVPtypeSerializer< true> ; 到
到
struct NVPtypeSerializer< false>
它可以在GCC上编译,但Clang给出以下错误:
If I change the struct NVPtypeSerializer<true>
to struct NVPtypeSerializer<false>
it can be compiled on GCC, but Clang gives the following error:
error: no member named 'serialize' in 'Bar'
b $ b
问题在哪里?它在我的代码?
Where is the problem? Is it in my code? I'd like to have the code portable as much as possible.
推荐答案
这真的是代码 test(char [sizeof(& C :: serialize)])
?注意,接受数组的函数的声明实际上声明一个接受指针的函数:
Is this really the code test(char[sizeof(&C::serialize)])
? Note that a declaration of a function that takes an array actually declares a function that takes a pointer:
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
这实际上意味着:
template <typename C> static yes& test( char* );
这是什么使得你的调用 test< C>(0) / code>编译。我不认为这是检测函数是否存在的正确方法。 Google如何在使用SFINAE的类中检测成员/成员函数是否存在。
Which incidentally is what makes your call test<C>(0)
compile. I don't think that is the proper way of detecting whether the function exists or not. Google on how to detect whether a member/member function exists in a class using SFINAE.
(一个简单的解决方案是添加一个额外的默认参数 - 一个启用C ++ 11的编译器:
(A simple solution would be adding an extra defaulted argument --provided that you have a C++11 enabled compiler:
template <typename C, std::size_t = sizeof(&C::serialize)>
static yes& test(int) ;
)
这篇关于使用SFINAE在GCC和Clang上给出不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!