Fed*_*dor 4 c++ sfinae incomplete-type
我想编写一个 C++ 函数来检查其模板参数类是否不完整,因此只有类声明可用,但没有所有类成员的完整定义。
我的函数incomplete()与一些演示程序如下所示:
#include <type_traits>
#include <iostream>
template <typename T, typename V = void> constexpr bool is_incomplete = true;
template <typename T> constexpr bool is_incomplete<T, std::enable_if_t<sizeof(T)>> = false;
template <typename T> constexpr bool incomplete() { return is_incomplete<T>; }
struct A;
void print() { std::cout << incomplete<A>(); }
struct A {}; //this line affects GCC
int main()
{
print();
}
Run Code Online (Sandbox Code Playgroud)
它在 Clang 打印中运行良好,但在 GCC 中,尽管类的功能不完整,1程序仍会打印。
https://gcc.godbolt.org/z/qWW3hqbEv0Aprint
是 GCC 错误还是我的程序有问题?
目前尚未确定哪个编译器是正确的。这是CWG 第 1845 期。
\n\n\n13.8.4.1 [temp.point] 的当前措辞没有定义变量模板特化的实例化点。大概将第 1 段和第 8 段中对类 template\xe2\x80\x9d 的 \xe2\x80\x9cstatic 数据成员的引用替换为 \xe2\x80\x9cvariable template\xe2\x80\x9d 就足够了。
\n
鉴于该问题仍处于起草阶段(最新草案尚无规范性措辞),因此仍未解决。目前尚不清楚变量模板是否可以具有多个实例化点(尽管问题报告者建议的方向很明确)。
\n对于具有多个实例化点的实体,翻译单元的末尾也是一个。此外,如果两点在模板的定义上存在分歧,那么这就是 ODR 违规,简单明了。GCC 似乎提供了两点,所以你看到了结果。我倾向于同意 GCC 的观点。变量模板在很多方面都是类模板的静态数据成员的简写,并且静态数据成员确实具有多个实例化点。
\n不管怎样,这都是在冒鼻恶魔的风险。如果该状态可以在 TU 中更改(甚至可能在整个程序中更改),则实际上不可能可靠地检查类型的完整性。
\n