【问题标题】:Template deduction for default template argument默认模板参数的模板推导
【发布时间】:2018-05-11 13:40:38
【问题描述】:

我有一个类似这样的类:

template <class T = char>
struct C {
    T value;
};

直到 C++14,当我想将它与默认模板参数一起使用时,我总是必须指定空尖括号:

void f() {
    C<> c;
    c.value = 'x';
}

由于 C++17 支持类模板参数推导和显式推导指南,我想知道现在是否有一种方法可以在不指定空尖括号的情况下使上述代码工作:

void f() {
    C c;
    c.value = 'x';
}

如果我使用-std=gnu++17 编译此代码,它可以在 GCC 8.0 中运行。但是,它在 Clang 6.0 和 Visual Studio 15.7 中仍然显示错误。在这种情况下哪个编译器是正确的?

我也试过这样指定一个扣除指南:

C() -> C<char>;

这也没有帮助。这是正确的语法还是有办法为默认构造函数指定推导指南?

【问题讨论】:

  • 注意C c; c.value = 42;不会将类型推导为int,只在构造时进行推导。
  • @Jarod42 是的,我知道。这只是作为例子。如果使用默认模板参数,我的意图是去掉空尖括号。

标签: c++ c++17


【解决方案1】:

这个程序是正确的:

template <class T = char>
struct C {
    T value;
};

int main() {
    C c;
    c.value = 'x';
}

clang 还不完全支持类模板参数推导(注意它确实在主干上编译)。


类模板参数推导将尝试对候选集执行重载解析:

template <class T=char> auto __f()     -> C<T>
template <class T=char> auto __f(C<T>) -> C<T>

没有初始化器。第一个是可行的候选者(将T 推断为char),第二个不是,所以第一个是最可行的候选者。所以我们最终得到c 类型为C&lt;char&gt;。然后,当我们对默认构造进行重载解析时,这是可行的,所以程序很好。

【讨论】:

    猜你喜欢
    • 2012-11-18
    • 2023-01-24
    • 1970-01-01
    • 2021-05-23
    • 2018-07-04
    • 1970-01-01
    • 2021-11-01
    • 2020-11-02
    • 2020-02-27
    相关资源
    最近更新 更多