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

acu*_*tea 2 c++ templates template-argument-deduction c++17

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

这编译为g++ -std=c++17

template<typename T>
struct foo{
    T x;
    foo(T _x):x(_x){}
};
auto x=foo(3);
Run Code Online (Sandbox Code Playgroud)

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

template<typename T>
struct foo{
    T x;
    foo(decltype(x) _x):x(_x){}
};
auto x=foo(3);
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 5

你写的是一种循环逻辑。像这样想。

编译器看到foo(3). foo命名一个类模板,因此它尝试执行类模板参数推导以找出Tinfoo应该是什么。

CTAD 开始时去掉所有构造函数并从中构建模板推导指南。您有一个构造函数,因此它的指南必须如下所示:

template<typename T> foo(decltype(foo<T>::x) _x) -> foo<T>;
Run Code Online (Sandbox Code Playgroud)

为了推导出模板参数Tfoo,你就需要实例foo...用T。你还没有,因为弄清楚是什么T是你首先建立这个演绎指南的原因。