Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在模板SFINAE约束中使用间接级别会导致硬错误_C++_Templates_Language Lawyer_C++17_Sfinae - Fatal编程技术网

C++ 在模板SFINAE约束中使用间接级别会导致硬错误

C++ 在模板SFINAE约束中使用间接级别会导致硬错误,c++,templates,language-lawyer,c++17,sfinae,C++,Templates,Language Lawyer,C++17,Sfinae,在下面的代码中() 当我删除此()约束中带有Identity的间接寻址时,错误就会消失 模板< 类型名T, typename U=std::衰变, std::如果启用,则启用< std::is_constructible::value>*=nullptr> 显式某物(T&{}; 根据我的理解,这里的问题是我们试图实例化std::is_constructible,然后实例化某物的构造函数,然后再实例化std::is_constructible,依此类推 但是,当我尝试在没有Identity的情况

在下面的代码中()

当我删除此()约束中带有
Identity
的间接寻址时,错误就会消失

模板<
类型名T,
typename U=std::衰变,
std::如果启用,则启用<
std::is_constructible::value>*=nullptr>
显式某物(T&{};
根据我的理解,这里的问题是我们试图实例化
std::is_constructible
,然后实例化
某物的构造函数,然后再实例化
std::is_constructible
,依此类推


但是,当我尝试在没有
Identity
的情况下编译此文件时,为什么错误会消失呢?当我使用
Identity
时,为什么会出错?

您已经知道存在一个“递归实例化”。没有真正的递归;在“有效”的情况下发生的情况很简单,当考虑构造函数模板以确定从
const Something&
进行的构造是否会成功时,
std::is_constructible
没有成员
。(与普遍的看法相反,类
C
不需要完整才能使用
C:::
命名成员-但是命名成员必须已经声明,并且“已经”的确切含义是。)

该错误位于构造函数模板的即时上下文中,因此该模板将被静默忽略。(在这种情况下,这没有什么区别:(已删除的)复制构造函数更匹配,因为它不是模板。)这确定了缺失的
值是
false
,这至少与第一次拒绝构造函数模板的情况一致。这可能违反了
std::is_constructible
本身的专门化;如果我们否定了<代码> Enable中的条件,如果< /COD>控制它自己,那么Helistic就随之而来。


您的
Identity
遇到相同的错误(或者相关专业化尚未完成的更普遍的问题)。作为辅助实例化的一部分,错误是不可恢复的。

是可构造的。\u v
是从C++17开始的,只是为了简化我头脑中的代码:
std::is_constructible
不是从它的任何一个参数继承的,因此它在不同于您的标识类的约束下运行。这是否也意味着[meta.unary.prop]/表47,关于
std::is_constructible
模板参数的完整性先决条件,违反了“
T
和参数包
Args
中的所有类型都应为完整类型”(在两个示例中)?@dfri:No默认模板参数直到需要时才会实例化,当
某个东西
很长时间完成时。我不确定是否会这样做,如果我不从它继承并直接使用值成员,那么为什么错误仍然存在?@好奇:我过分强调了完整性问题,对不起。
的查找同样失败由于继承while
是可构造的
正在被实例化,并且同样超出了直接上下文。我添加了更多解释性细节,并将重新措辞以避免对完整性的混淆。
#include <type_traits>

template <typename T>
struct Identity : public T {};

class Something {
public:
  Something() = default;
  Something(const Something&) = delete;
  Something(Something&&) = default;
  Something& operator=(const Something&) = default;
  Something& operator=(Something&&) = default;

  template <
      typename T,
      typename U = std::decay_t<T>,
      std::enable_if_t<Identity<
        std::is_constructible<U, T&&>>::value>* = nullptr>
  explicit Something(T&&) {};
};

int main() {
    static_cast<void>(std::is_constructible<Something, const Something&>{});
}
error: base class has incomplete type
struct Identity : public T {};
                  ~~~~~~~^
  template <
      typename T,
      typename U = std::decay_t<T>,
      std::enable_if_t<
        std::is_constructible<U, T&&>::value>* = nullptr>
  explicit Something(T&&) {};