Luk*_*rth 21 c++ gcc language-lawyer c++17
I'm trying to get this is-class-defined-check to work, which relies on the fact that decltype(std::declval<Foo>().~Foo()) is void if Foo has a destructor (which it has if it is defined…) and is ill-formed otherwise, invoking SFINAE in this case.
However, I can't get the code to work with GCC 9.1, and that is because GCC 9.1 seems to consider that type to be void & if the destructor is defaulted, consider this example:
#include <type_traits>
class Foo {
public:
// With this, the DestructorReturnType below becomes "void"
//    ~Foo () {} 
};
// … unless I specify the user-defined destructor above, in which case it is "void"
using DestructorReturnType = decltype(std::declval<Foo>().~Foo());
template<class T>
class TD;
// Says: aggregate 'TD<void&> t' has incomplete type and cannot be defined
TD<DestructorReturnType> t;
(available at https://gcc.godbolt.org/z/K1TjOP )
If I user-define an empty destructor, the type jumps back to void. Also if I switch back to GCC 8.x.
The C++17 standard states in [expr.call]:
If the postfix-expression designates a destructor, the type of the function call expression is void; […]
Because of all this, I suspect that GCC 8.x (and clang, …) are correct, and GCC 9.1 is just wrong. Or am I missing something?
Luk*_*rth 12
长话短说:是的,这是GCC 9.1中的回归。void&甚至不是有效的类型,所以有些错误。显然,可以通过设置-fno-lifetime-dse编译器选项来解决此问题,而以(可能的)轻微的性能代价为代价。此外,9.1之前的GCC版本也不受影响。
如果您因为也在尝试实现上述is-class-defined-check而找到了答案,那么我认为使用sizeof的简单得多的表单应该定义明确,有效并且不会受到此bug的攻击。
| 归档时间: | 
 | 
| 查看次数: | 578 次 | 
| 最近记录: |