【发布时间】:2014-05-11 07:23:50
【问题描述】:
假设我们有两种类型(完整的和不完整的):
struct CompleteType{};
struct IncompleteType;
我们还有模板代码:
#include <type_traits>
template <typename = X(T)>
struct Test : std::false_type {};
template <>
struct Test<T> : std::true_type {};
T 在这里可以是CompleteType 或IncompleteType,X(T) 可以是T、decltype(T()) 或decltype(T{})(假设X(T) 是一个宏)。
此代码的使用方式如下:
std::cout << std::boolalpha << Test<>::value << std::endl;
您可以在下面看到不同的编译器如何处理此类代码:
clang 3.4
X(T) \ T CompleteType IncompleteType
T true true
decltype(T()) true --- (1, 2)
decltype(T{}) true --- (1, 2)
即使在具有不完整类型的模板类声明(
decltype(T())和decltype(T{}),但不是简单的T)上也给出error: invalid use of incomplete type 'IncompleteType',而不在代码中使用Test<>::value。error: too few template arguments for class template 'Test'
g++ 4.8.1
X(T) \ T CompleteType IncompleteType
T true true
decltype(T()) true true
decltype(T{}) true true
vc++ 18.00.21005.1
X(T) \ T CompleteType IncompleteType
T true true
decltype(T()) true --- (1)
decltype(T{}) true --- (2)
error C2514: 'IncompleteType' : class has no constructorserror C2440: '<function-style-cast>' : cannot convert from 'initializer-list' to 'IncompleteType' Source or target has incomplete type
什么编译器符合标准?请注意,std::cout << typeid(X(IncompleteType)).name() << std::endl; 之类的简单字符串不会在所有编译器上编译 X 的所有变体(vc++ 除外) 和 X(T) == T)。
【问题讨论】:
-
“X(T) can be T, decltype(T()) or decltype(T{})”是什么意思?
X(T)是X(T)。怎么可能是T或decltype(T())或decltype(T{})?所有这些都是不同的类型,并且永远不会是相同的函数类型! -
@JohannesSchaub-litb 假设
X(T)是宏。 -
如果您不希望它成为一个坏问题,则应将其写在您的问题中
-
我无法重现代码,但我很好奇如果你这样做会发生什么
struct CompleteType { CompleteType() = delete;}; -
(以防万一,用 g++ 的结果仍然是真实的)
标签: c++ templates c++11 incomplete-type