Cor*_*sto 5 c++ templates sfinae language-lawyer libc++
我刚刚观察到libc ++的一个奇怪问题,当使用SFINAE来检测模板类型是否是默认构造时.
以下是我能够提出的最小例子:
#include <iostream>
#include <type_traits>
template <typename T>
struct Dummy;
template <>
struct Dummy<int>{};
template <typename T, typename = void>
struct has_dummy : std::false_type {};
template <typename T>
struct has_dummy<C, std::enable_if_t<std::is_default_constructible<Dummy<T>>::value>> : std::true_type{};
int main() {
std::cout << std::boolalpha << has_dummy<int>{}() << '\n';
std::cout << std::boolalpha << has_dummy<double>{}() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
它编译并输出预期的行,true
并false
在使用时使用g ++或clang ++编译libstdc++
.但是,当我尝试使用libc ++(即clang++ -stdlib=libc++ -std=c++1z test.cpp
)编译它时,我收到以下错误:
/usr/bin/../include/c++/v1/type_traits:2857:38:错误:隐式实例化未定义模板'Dummy':public integral_constant
/usr/bin/../include/c++/v1/type_traits:3166:14:注意:在这里请求模板类'std :: __ 1 :: is_constructible>'的实例化:public is_constructible <_Tp>
test.cpp:14:43:注意:在这里请求模板类'std :: __ 1 :: is_default_constructible>'的实例化
struct has_dummy<T, std::enable_if_t<std::is_default_constructible<Dummy<T>>::value>> : std::true_type{};
test.cpp:18:35:注意:在模板参数推导期间进行类模板局部特化
'has_dummy<type-parameter-0-0, typename enable_if<std::is_default_constructible<Dummy<T> >::value, void>::type>' [with T = double]
Run Code Online (Sandbox Code Playgroud)std::cout << std::boolalpha << has_dummy<double>{}() << '\n';
test.cpp:5:8:注意:模板在这里声明
struct Dummy;
这是在libc中++的实现的一个bug std::enable_if
或std::is_default_constructible
或我在做什么莫名其妙调用未定义/实施的具体行为?
最好的Corristo
is_default_constructible
国家的先决条件非常明确:
N4140§20.10.4.3[meta.unary.prop]/
is_default_constructible
row
T
应该是一个完整的类型,(可能是cv -qualified)void
,或者是一个未知界限的数组.
根据以下内容,您的程序显示未定义的行为:
N4140§17.6.4.8[res.on.functions]/2
在以下情况下,效果未定义:
- [...]
- 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件.