gpt4 book ai didi

c++ - SFINAE 使用 VoidT 和不同的编译器会导致不同的结果

转载 作者:行者123 更新时间:2023-12-01 18:07:42 25 4
gpt4 key购买 nike

考虑以下代码:

template <typename T> using VoidT = void;

class A {
public:
using TEST = int;
};

class C {
public:
using DIFFERENT = int;
};

template <typename T, typename Enable = void>
class B {
public:
B() = delete;
};

template <typename T>
class B<T, VoidT<typename T::TEST>> {
public:
B() = default;
};

template <typename T>
class B<T, VoidT<typename T::DIFFERENT>> {
public:
B() = default;
};

int main() {
B<A> a;
B<C> b;

return 0;
}

使用 g++-4.8.5 编译此代码会出现以下错误消息:

~/test/compile_test> g++ -std=c++11 test.cpp

test.cpp:31:7: error: redefinition of ‘class B<T, void>’

test.cpp:24:7: error: previous definition of ‘class B<T, void>’

但是,当我使用 g++-8.3(例如在 ideone 中)编译时,代码会编译并且不同的特化会被正确处理。这是 GCC 中已修复的错误,还是我以某种方式调用了未定义的行为(因此编译器行为的差异是一个有争议的点 - 它是未定义的)?

最佳答案

Was this a bug in GCC that was fixed?

这是标准中的缺陷。它已针对以前的标准版本进行了追溯修复,但当然只有较新的编译器版本才会修复。这是CWG Issue 1558 ,并引用其中:

The treatment of unused arguments in an alias template specialization is not specified by the current wording of 17.6.7 [temp.alias]. For example:

  #include <iostream>

template <class T, class...>
using first_of = T;

template <class T>
first_of<void, typename T::type> f(int)
{ std::cout << "1\n"; }

template <class T>
void f(...)
{ std::cout << "2\n"; }

struct X { typedef void type; };

int main() {
f<X>(0);
f<int>(0);
}

Is the reference to first_of with T being int equivalent to simply void, or is it a substitution failure?

没有 DR 修复的编译器的解决方法是使用助手:

template<typename T> struct voider { using type = void; };
template <typename T> using VoidT = typename voider<T>::type;

在类模板中保证替换失败。

关于c++ - SFINAE 使用 VoidT 和不同的编译器会导致不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58325738/

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