gpt4 book ai didi

c++ - 使用 SFINAE 在 GCC 和 Clang 上给出不同的结果

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:32 25 4
gpt4 key购买 nike

我正在学习如何利用 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);
};

然而,它似乎在 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();
}
};

这样调用:

foo = NVPtypeSerializer<HasSerialize<Bar>::value >::serialize(value);

类(class)所在Bar没有 serialize()功能。此代码在 Clang 3.1 下编译良好,但在 GCC 4.7.1 上我收到以下错误:

error: ‘class Bar’ has no member named ‘serialize’

如果我更改 struct NVPtypeSerializer<true>struct NVPtypeSerializer<false>它可以在 GCC 上编译,但 Clang 给出以下错误:

error: no member named 'serialize' in 'Bar'

问题出在哪里?它在我的代码中吗?我希望代码尽可能具有可移植性。

最佳答案

这真的是密码吗test(char[sizeof(&C::serialize)]) ?请注意,声明一个接受数组的函数实际上声明了一个接受指针的函数:

template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;

这实际上意味着:

template <typename C> static yes& test( char* );

顺便说一下,这就是您的电话 test<C>(0)编译。我不认为这是检测函数是否存在的正确方法。 Google 关于如何使用 SFINAE 检测类中是否存在成员/成员函数。

(一个简单的解决方案是添加一个额外的默认参数——假设您有一个支持 C++11 的编译器:

template <typename C, std::size_t = sizeof(&C::serialize)> 
static yes& test(int) ;

)

关于c++ - 使用 SFINAE 在 GCC 和 Clang 上给出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11566564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com