为什么在 ctor 的参数列表中将成员"x"的类型替换为"decltype(x)"会破坏类模板参数推导?

Why does replacing the type of the member `x` with `decltype(x)` in a ctor's argument list break class template argument deduction?

本文关键字:参数 替换 列表 ctor 成员 为什么 类型 decltype      更新时间:2023-10-16

我正试图编写某种预处理器怪物来制作简单的actor。

这与g++ -std=c++17:一起编译

template<typename T>
struct foo{
T x;
foo(T _x):x(_x){}
};
auto x=foo(3);

但怪物很难知道x的类型,所以我尝试了这个:

template<typename T>
struct foo{
T x;
foo(decltype(x) _x):x(_x){}
};
auto x=foo(3);

失败(class template argument deduction failed(。但无论如何,decltype(x)就是T,对吧?那么,为什么代码示例不等价呢?

您所写的是一种循环逻辑。这样想吧。

编译器看到foo(3)foo命名了一个类模板,因此它试图执行类模板参数推导,以找出foo中的T应该是什么

CTAD一开始就去掉了所有的构造函数和构建模板推导指南。你有一个构造函数,所以它的指南必须看起来像:

template<typename T> foo(decltype(foo<T>::x) _x) -> foo<T>;

为了推导foo的模板参数T,您需要实例化foo。。。具有CCD_ 13。你还没有,因为弄清楚T是什么是你最初构建这个推导指南的原因。

这里的简短答案是因为C++标准是这么说的。decltype表达式不能作为模板参数推导出来。

17.8.2.5从类型〔temp.decture.type〕中推导模板参数

未推导的上下文为:

[…]

--decltype说明符的表达式。

您正在使用C++17。如果你使用decltype来隐藏一些怪物,你可能需要使用C++17的推导指南来解决它