c++ - 关于为模板提供默认类型的问题

标签 c++

比如我写了下面这段代码:

struct default_type {};

template <typename U = default_type> auto func(int x, U u) {
    if constexpr(is_same<U, default_type>::value) {
        return x * 2;
    }
    else {
        return u(x);
    }
}

int main() {
    cout << "5 + 3 = " << func(5, [](int x){ return x + 3; }) << endl;
    cout << "5 * 2 = " << func(5) << endl;
}

但这会给出一个编译器错误“没有匹配函数来调用‘func(int)’”。执行此操作的正确方法是什么?

最佳答案

您提供了默认类型,但没有提供默认值。该函数仍然需要两个参数,default_type 将被推导的参数覆盖,使其无用。

这样做:

template <typename U = default_type>
auto func(int x, U u = {}) { ... } // (1)

我不能用确切的标准来支持这一点,但简而言之:U 是在模板参数推导 阶段获得的(没有推导规则 - 不考虑默认值function arguments, therefore defaulted),它出现在重载解析阶段之前,此时默认函数参数被解释,已经知道 U 的类型,这使得列表初始化有效。


是的,你也可以这样写:

template <typename U = default_type>
auto func(int x, U u = U()) { ... } // (2)

template <typename U = default_type>
auto func(int x, U u = default_type()) { ... } // (3)

当显式提供 U 类型时语义略有不同(我不认为你会这样做):

func<not_the_default_type>(5);

这里,(1) 和 (2) 是等价的,但是在 (3) 中,U 的构造是通过构造一个临时的 default_type 实现的,然后将其转换为 not_the_default_type


最后,完全相反的错误是期望 U 在这里推导:

template <typename U>
auto func(int x, U u = default_type()) { ... }

事实并非如此。参见 this Q&A .

关于c++ - 关于为模板提供默认类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55819654/

相关文章:

c++ - 使 QtConcurrent::mapped 与 lambda 一起工作

c++ - 带有map()/mapto()函数的C/C++库?

c++ - 防止混合调试和发布库

c++ - 只有一个常数项发生变化时线性系统Ax= b的高效求解

c++ - cornerSubPix() 可以检测到的最大角点数

C++ Map插入具有重复键的对

c++ - 验证器断言失败

.hpp 文件中静态函数的 C++ 链接器错误

c++ - 如何修复构建时缺少的 .pch 文件?

c++ - 创建一个计算器 C++