这有什么问题:
#include <type_traits>
struct A;
template<typename T>
struct B
{
template<typename=std::enable_if<std::is_copy_constructible<T>::value>>
void f1() {}
};
template<typename T>
struct C {};
// Type your code here, or load an example.
int main() {
// Following fails
B<A> b;
// Could use this:
// b.f1<C>();
// This complies
C<A> c;
return 0;
}
/* This to be in or not doesn't make a difference
struct A
{};
*/
我在这里尝试过:https://godbolt.org/z/NkL44s使用不同的编译器:
- x86-64 gcc 9.2:编译
- x86-64 gcc(主干):失败
- x86-64 clang 6.0.0:编译
- x86-64 clang 7.0.0 及更高版本:失败
- x64 msvc v19.22:编译
- x64 msvc v19.23(内部测试):失败
那么为什么最近的编译器拒绝这个呢?实例化时B<A>
目前尚不清楚以哪种形式 f1
将被使用或者是否会被使用。那么为什么编译器会提示它呢?不应该f1
成员模板函数只有在真正使用时才检查吗?
编辑:
正如评论中提到的,我在上面的代码中犯了一个无意的错误:std::enable_if
应该是std::enable_if_t
,如在这个更正后的 Playground 中:https://godbolt.org/z/cyuB3d
这改变了编译器传递此代码而没有错误的情况:
- gcc:失败
- clang:失败
- x64 msvc v19.22:编译
- x64 msvc v19.23(内部测试):失败
但是,问题仍然存在:为什么从未使用过的函数的默认模板参数会导致编译失败?
最佳答案
原因是 std::is_constructible
需要完整的类型:( Table 42 )
Template
template <class T> struct is_copy_constructible;
Preconditions
T
shall be a complete type, cv void, or an array of unknown bound.
未能满足库“应”的要求会导致未定义的行为。
关于c++ - 为什么未使用的成员模板函数的类模板实例化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58320421/