SFINAE与std :: enable_if和std :: is_default_constructible用于libc ++

时间:2016-11-26 18:57:32

标签: c++ templates language-lawyer sfinae libc++

当我使用SFINAE来检测模板类型是否是默认构造时,我刚刚观察到libc ++的一个奇怪问题。

以下是我能够提出的最小例子:

#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';
}

使用true编译时,使用g ++或clang ++编译时,它会编译并输出预期的行falselibstdc++。但是,当我尝试使用libc ++(即clang++ -stdlib=libc++ -std=c++1z test.cpp)编译它时,我收到以下错误:

  

/ usr / bin /../ include / c ++ / v1 / type_traits:2857:38:错误:未定义模板的隐式实例化        '假'       :public integral_constant

     

/ usr / bin /../ include / c ++ / v1 / type_traits:3166:14:注意:在模板类的实例化中         '的std :: __ 1 :: is_constructible&GT;'这里要求       :public is_constructible&lt; _Tp&gt;

     

test.cpp:14:43:注意:在模板类'std :: __ 1 :: is_default_constructible&gt;'的实例化中         这里要求 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]

   std::cout << std::boolalpha << has_dummy<double>{}() << '\n';
     

test.cpp:5:8:注意:模板在这里声明   struct Dummy;

这是libc ++的std::enable_ifstd::is_default_constructible实现中的错误,还是我正在以某种方式调用未定义/实现特定的行为?

最佳

Corristo

1 个答案:

答案 0 :(得分:7)

is_default_constructible状态的先决条件非常明确:

  

N4140§20.10.4.3[meta.unary.prop] / is_default_constructible

     

T应为完整类型,(可能 cv -qualified)void,或者   未知界限的阵列。

根据以下内容,您的程序显示未定义的行为:

  

N4140§17.6.4.8[res.on.functions] / 2

     

在以下情况下效果未定义:

     
      
  • [...]
  •   
  • 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许   该组件。
  •