有关为模板提供默认类型的问题

时间:2019-04-23 21:27:53

标签: 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)'”。正确的方法是什么?

1 个答案:

答案 0 :(得分:3)

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

执行以下操作:

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

我不能完全按照标准的标准来支持这一点,但是简而言之:U是在模板参数推导阶段获得的(没有推导规则-不考虑默认函数参数, (因此为默认值),该值位于重载解析阶段之前,此时,已经知道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