c++ - 在模板 SFINAE 约束中使用间接级别会导致硬错误
问题描述
在以下代码中(https://wandbox.org/permlink/rA7lnXM6eQR4JhSM)
#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 {};
~~~~~~~^
Identity
当我删除约束中的间接时,错误消失了( https://wandbox.org/permlink/MFJCHUzeKnS4yR0d)
template <
typename T,
typename U = std::decay_t<T>,
std::enable_if_t<
std::is_constructible<U, T&&>::value>* = nullptr>
explicit Something(T&&) {};
据我了解,这里的问题是我们正在尝试实例化std::is_constructible
,然后实例化构造函数Something
,然后实例化std::is_constructible
,依此类推。
但是,当我尝试在没有 的情况下编译它时,为什么错误会消失Identity
?为什么我使用时会出错Identity
?
解决方案
您已经知道存在“递归实例化”。没有真正的递归;在“有效”的情况下发生的事情很简单,当考虑构造函数模板以找出从 a 的构造是否const Something&
会成功时,还std::is_constructible<Something, const Something&>
没有成员。(与普遍的看法相反,一个类不需要是完整的来命名一个成员——但命名的成员必须已经被声明了,“已经”的确切含义有点模糊。)value
C
C::
该错误位于构造函数模板的直接上下文中,因此模板被静默忽略。(这在这种情况下没有区别:(已删除的)复制构造函数是更好的匹配,因为它不是模板。)这确定了value
缺少的是false
,这至少与第一次拒绝构造函数模板一致. 这可能违反[meta.rqmts]/5本身的专业化std::is_constructible
;enable_if
考虑一下,如果我们否定控制自身的条件,就会产生欢闹。
您Identity
遇到相同的错误(或相关专业化的更一般问题尚未完成)。作为辅助实例化的一部分,该错误是不可恢复的。
推荐阅读
- sql - mssql:为所有行添加具有相同值的列到搜索结果
- c# - 如何将 EPPlus 中创建的图表导出到图像文件
- asp.net-mvc - Using Business Object As Model is not working?
- python - OpenCV 的这个功能哪里去了?
- firebase - JS函数在promise解析之前返回值
- javascript - 在Interval React.js中乘以数字时如何获得索引0
- javascript - 悬停在父元素上但不影响子元素
- angular - 在 Angular 7 中实现 bcrypt
- c# - 无法使用 EF Code First 以 1 : 1 映射将记录保存到数据库
- firewalld - 单位 firewalld.service 找不到