【问题标题】:C++ : Function overloading vs Variadic function vs Variadic template vs default parameter [closed]C ++:函数重载vs可变参数函数vs可变参数模板vs默认参数[关闭]
【发布时间】:2015-05-08 20:49:13
【问题描述】:

我看过这些问题:

但他们不考虑可变参数函数和可变参数模板。

考虑编写一个函数来求 2 个或 3 个正数的平均值的问题。

我们可以通过四种方式来实现这个功能:

  1. 使用默认参数:

    int average(int x , int y , int z=-1);
    
  2. 使用函数重载:

    int average(int x , int y);
    int average(int x , int y , int z);
    
  3. 使用variadic function

    int average(int x,int y, ...);
    
  4. 使用variadic template

    int sum=0;
    int count=0;
    void average(){
       return;
    }
    template <class A, class ...B> void average(A argHead, B... argTail){
       sum =sum+argHead;
       count+=1;
       average(argTail...);
    }
    

使用一种方法相对于另一种方法的优缺点是什么?

【问题讨论】:

  • 3 不是类型安全的。在 1 和 2 之间进行选择取决于函数在做什么。
  • 如你所见,他们都必须解决同样的问题。
  • 另外,对于数字 3,您并不真正知道有多少参数,您需要手动从堆栈中获取参数并转换为正确的类型(同时希望用户传递正确值)。
  • 关于 1 和 2,仅针对此特定用例,对于 1,您必须在函数内部保留一个特殊情况以检查 z 是否为 -1 并且不使用其中的变量案子。使用方法 2,您不需要任何特殊情况。
  • @JoachimPileborg 您提供的是差异而不是利弊。

标签: c++ performance function variadic-templates variadic-functions


【解决方案1】:

考虑到约束,即两个或三个正数的平均值,第二个选项是最好的。

第一个选项,带有可选参数,需要进行积极性测试:

int average(int x,int y,int z=-1) {
    if (z<0) return (x+y)/2;
    else return (x+y+z)/3;
}

就提供求平均值服务而言,该测试是不必要的。此外,它很脆弱:考虑找到也可能为负的数字的平均值是合理的,并且这种解决方案与这种情况不兼容。

第三个选项,可变参数函数,不合适,因为您需要在调用中提供信息以指示存在多少参数,例如以负数结尾,或第一个参数指示剩余参数的数量。这使界面复杂化。此外,它不是类型安全的,因此函数的用户有责任谨慎地只使用ints 调用它——编译器不会禁止或警告错误的使用。

使用可变参数模板是一种很好的通用解决方案,可以轻松扩展到任意数量的参数。但在这里,我们只需要两个和三个参数情况,因此对于应用程序来说过于复杂。但是,如果要使用它,则需要使用不需要全局变量的不同实现。下面使用命名空间来隐藏一些实现细节,并通过在递归前固定头部类型来强制使用int参数:

namespace impl {
    int sum() { return 0; }

    template <typename... V>
    int sum(int a,V... rest) { return a+sum(rest...); }
}

template <typename... V>
int average(int a,V... rest) {
    return impl::sum(a,rest...)/(1+sizeof...(V));
}

【讨论】:

猜你喜欢
  • 2021-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2011-05-07
  • 1970-01-01
相关资源
最近更新 更多