c++ - 默认模板参数的模板推导

标签 c++ c++17

我有一个类似于此的类:

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>;

这也没有帮助。这是正确的语法,还是有一种方法可以为默认构造函数指定推导指南?

最佳答案

这个程序是正确的:

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<char> .然后,当我们对默认构造进行重载决策时,它起作用了,所以程序没问题。

关于c++ - 默认模板参数的模板推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50293659/

相关文章:

c++ - 为什么队列接受 vector 作为其底层容器?

c++ - 防止使用重写的非虚函数 - 正确的方法?

c++ - 无法打印字符串数组元素

c++ - 如何获取 rand() (C++) 的源代码?

c++ - 评估重复单词出现的程序

c++ - static_cast 的指针值

c++ - C++11、14、17 或 20 是否为 pi 引入了标准常量?

c++ - 用于比较原始类型的 std::optional 的有趣程序集

C++17 和十进制浮点的当前状态

c++ - 结构到/从 std::tuple 转换