【问题标题】:Why c++ allows default template argument that can never be used?为什么 c++ 允许永远无法使用的默认模板参数?
【发布时间】:2020-11-05 21:12:36
【问题描述】:

如果我有一个函数模板,其模板参数具有默认参数,并且该函数采用类型参数的非默认参数,那么语言中允许永远不会使用的默认参数的意义何在? :

template <class T = int>
void foo(T x){cout << x << endl;}

int main()
{

    foo("hi"); // T is char const *
    foo(); // error
}

正如您所见,T=int 永远无法使用,因为该函数没有默认参数,因此在此上下文中的编译器总是从传递给foo 的参数中推断出T 的类型。

【问题讨论】:

  • 你的函数不带参数吗?调用一个需要参数的函数没有它意味着什么?
  • 几乎可以肯定,因为尝试实际证明类型推断对于某些给定函数总是可以成功的成本相对较高,并且在可以证明它处于这种情况时发出警告相对没有意义。

标签: c++ templates type-deduction default-arguments


【解决方案1】:

但它可以使用。这是一个例子。

auto* foo_ptr = &foo<>; // The default template argument is used.

函数调用表达式并不是唯一需要计算函数模板参数的上下文。

【讨论】:

  • 也许是一个更常见的例子:foo({})。 (更常见的情况是容器上的算法默认为值类型。)
【解决方案2】:

虽然默认参数通常用于非推导参数,但取函数的地址(&amp;foo)也使用它们。

【讨论】:

    【解决方案3】:

    另一个例子:

    #include <typeinfo>
    #include <iostream>
    using namespace std;
    
    template <class T = int>
    void coutType() {
        cout << typeid(T).name() << endl;
    }
    
    int main() {
        // default
        coutType();
        // non-default
        coutType<double>();
    }
    

    使用 Clang++ 输出

    int
    double
    

    【讨论】:

    • 与问题不严格相关,尽管它确实部分回答了它,因为这是默认模板参数的主要预期用例(并且在 OP 的情况下没有理由禁止它们,特别是作为存在其他用例,如其他答案所示)。
    • 不推荐发布其他示例答案吗?如果不推荐,我将不再发布其他示例答案。
    • @ClonD 通常,发布其他示例答案可能会有所帮助。但是,在这种特定情况下,OP 已经表明了对此类示例的认识,因此我不确定此答案的价值。 (OP 指出缺少函数参数的默认值。如果函数参数有默认值,则可以在没有参数的情况下调用函数,这基本上是您的示例。所以看起来这个问题是为了避免这个例子。)
    • @JaMiT 啊,我看不到 OP 的意识所以我的错误
    • @ColonD 我不是在抱怨,我是在解释我的投票;)
    【解决方案4】:

    语言中允许 [X] 的意义何在?

    更好:禁止 [X] 的意义何在?

    简单是有价值的。我会把举证责任交给想要让语言更复杂的一方。该语言允许模板参数具有默认值。该语言允许在直接调用函数时推导出模板参数。允许它们共存比添加禁止使用两者更简单。因此,我会问为什么禁止,而不是问为什么允许。如果并发症没有令人信服的理由,那么坚持简单。被允许做某事并不强迫一个人去做。也许有人(比如 StoryTeller 和 Dani)会发现这些东西的用途。

    当然,简单并不是最终的标准。如果伤害会来自 [X],那么这可能会超过简单性问题。并发症是合理的。但是,不应该仅仅因为某些东西似乎无用而引入复杂性。

    另一方面,可以合理地询问 [X] 是否可以使用。也许这才是真正的问题,即使 OP 没有意识到这一点。不过,我想我会提出一个解决问题的答案。

    【讨论】:

      猜你喜欢
      • 2015-02-20
      • 1970-01-01
      • 2018-04-30
      • 2012-02-14
      • 2016-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多