使用SFINAE与GCC一起使用但与Clang不一起使用的代码 [英] Code using SFINAE working with GCC but not with Clang

查看:105
本文介绍了使用SFINAE与GCC一起使用但与Clang不一起使用的代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在C ++ 11中使用SFINAE来实现序列化库.我的代码可以在GCC上正常运行,但不能在Clang上运行.我在这里将其简化为最少的代码:

I'm trying to use SFINAE in C++11 to implement a serialization library. My code works fine with GCC but not with Clang. I've reduced it here to a minimal code:

template <typename A, typename T>
constexpr auto has_save_method(A& ar, T& t) -> decltype(t.save(ar), bool()) {
        return true;
}

template<class A, typename T, bool has_save>
struct saver;

template<class A, typename T>
struct saver<A,T,true> {
        static void apply(A& ar, T& t) {
                t.save(ar);
        }
};

class MyClass {

        public:

        template<typename A>
        void save(A& ar) {
                // Save the instance in the archive
        }
};

class MyArchive {};

template<typename A, typename T>
void save_to_archive(A& ar, T& t) {
        saver<A,T,has_save_method(ar,t)>::apply(ar,t);
}

int main(int argc, char** argv) {
        MyClass x;
        MyArchive a;
        save_to_archive(a,x);
        return 0;
}

GCC编译时没有错误.但是,lang声给了我以下内容:

GCC compiles this without error. Clang, however, gives me the following:

test.cpp:30:28: error: non-type template argument is not a constant expression
         saver<A,T,has_save_method(ar,t)>::apply(ar,t);
                                   ^ 
test.cpp:36:2: note: in instantiation of function template specialization
       'save_to_archive<MyArchive, MyClass>' requested here
         save_to_archive(a,x);
         ^

正在发生什么,如何使它们在两个编译器中都能正常工作?

What is happening and how can I make it work with both compilers?

推荐答案

这看起来像是Clang问题,已在 HERE 中讨论过

This looks like a Clang issue as discussed HERE

另一种解决方案是使用 void_t把戏:

Another solution to do it is using void_t trick :

template <typename... T>
using void_t = void;

template <typename A, typename T, typename = void_t<>>
struct has_save_method {
  constexpr static bool value = false;
};

template <typename A, typename T>
struct has_save_method<A, T, void_t<decltype(std::declval<T&>().save(std::declval<A&>()))>> {
  constexpr static bool value = true;
};

并像这样使用它:

template<typename A, typename T>
void save_to_archive(A& ar, T& t) {
        saver<A,T,has_save_method<A, T>::value>::apply(ar,t);
}

这篇关于使用SFINAE与GCC一起使用但与Clang不一起使用的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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