gpt4 book ai didi

c++ - 使用 SFINAE 的代码与 GCC 一起使用,但不与 Clang 一起使用

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:12:39 25 4
gpt4 key购买 nike

我正在尝试使用 C++11 中的 SFINAE 来实现序列化库。我的代码适用于 GCC,但不适用于 Clang。我在这里将其缩减为最少的代码:

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 编译它没有错误。然而,Clang 给了我以下信息:

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);
^

发生了什么,我怎样才能让它与两个编译器一起工作?

最佳答案

这看起来像讨论的 Clang 问题 HERE

另一种解决方案是使用 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);
}

关于c++ - 使用 SFINAE 的代码与 GCC 一起使用,但不与 Clang 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38465615/

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