【问题标题】:Can C++ deduce argument type from default value?C++ 可以从默认值推断参数类型吗?
【发布时间】:2022-01-06 10:08:05
【问题描述】:

我尝试使用默认模板参数编写此函数:

template<typename A, typename B>
void func(int i1, int i2, A a, B b = 123){
    ...
}

在我看来,我可以这样称呼它:func(1, 2, 3) 并且编译器应该将类型 B 从默认值推导出为 int,但我得到 no instance of overloaded function
在这种情况下,是不是 C++ 构造不正确,编译器无法推断类型?

【问题讨论】:

  • 你认为func&lt;int, float&gt;(1,2,3)应该怎么做?
  • @KarlKnechtel 相当于调用 func(1,2,3,123)
  • 来吧,模板已经死了,就用void func(int i1, int i2, auto a, auto b = 123)吧。
  • @Vorac 同样的问题:func(1, 2, 3) 失败,因为无法推断出b 的类型。

标签: c++ templates default template-argument-deduction default-arguments


【解决方案1】:

函数中模板形参的类型不能从默认实参推导出来。如cppreference.com上的例子所示:

类型模板参数不能从函数的类型推导出来 默认参数:

template<typename T> void f(T = 5, T = 7); 

void g()
{
    f(1);     // OK: calls f<int>(1, 7)
    f();      // error: cannot deduce T
    f<int>(); // OK: calls f<int>(5, 7)
}

但是,您可以为模板参数指定默认参数:

template<typename A, typename B = int>
void func(int i1, int i2, A a, B b = 123){
    ...
}

【讨论】:

  • 有趣的是,这个改动还允许用func(1,2, 3, {});进行扣减
  • @Deduplicator Braced-init-list 属于非推导上下文,因此不会进行推导,而是使用默认参数int。然后{}作为参数传递,b类型的参数int被初始化为值0
  • 我知道,只是想补充一点,此后此调用也有效。
【解决方案2】:

通常,当默认参数不起作用时,您可以使用重载:

template<typename A, typename B>
void func(int i1, int i2, A a, B b){
    ...
}
template<typename A>
void func(int i1, int i2, A a){
    func(i1,i2,a,123);
}

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多