使用SFINAE在GCC和Clang上给出不同的结果 [英] Using SFINAE gives different results on GCC and Clang

查看:214
本文介绍了使用SFINAE在GCC和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆