2013-03-05 32 views
2

编辑:我很高兴看到,有一个C++ 11的解决方案。无论如何,还没有人想出C++ 98的答案。所以,即使我已经接受了答案,问题依然存在。如何创建一个不需要调用者将参数传递给它的可变参数?

让我们假设你有一个命名空间中的一个函数:

namespace Math 
{ 
    int Sum(<params>); 
} 

如何实现这一功能的数学::总和,从而调用者可以使用任意数量的参数调用它尚未调用者不还需要传递参数的数量。 来电者还需要在呼叫地点完全符合资格。例如: Math::Sum(2, 4, 6, 8, 10, 12)

+0

宏?可变参数? eurgh,不,谢谢 – 2013-03-05 12:54:58

+0

好吧,有时候,即使在最新的编译器上,你也需要一些宏魔法来将它们屈服于你的意志;) 特别是当它们不完全符合C++ 11时:( – 2013-03-05 13:23:18

回答

7

这里是一个工作的一般方法,在C++ 11,与任何类型的辅助添加剂经营者(operator +):

#include <iostream> 
#include <string> 

template<typename T, typename U> 
auto Sum(T&& t, U&& u) -> decltype(t + u) 
{ 
    return (t + u); 
} 

template<typename T, typename... Ts> 
auto Sum(T&& t, Ts&&... ts) -> decltype(
    t + Sum(std::forward<Ts>(ts)...) 
    ) 
{ 
    return t + Sum(std::forward<Ts>(ts)...); 
} 

int main() 
{ 
    std::cout << Sum(1, 2, 3) << std::endl; 
    std::cout << Sum(1.0, 2.0, 3.0) << std::endl; 
    std::cout << Sum(std::string("Hello "), std::string("World!")) << std::endl; 
} 
+0

谢谢。一个观察结果是,它只适用于编译器与variadic模板支持,但是它支持多种类型的附加好处我相信 – 2013-03-05 13:02:42

+0

@ Zadirion:是的,我认为这是可以接受的,因为你将问题标记为“C++ 11” – 2013-03-05 13:04:09

+0

确实这是完全可以接受的。 – 2013-03-05 13:05:25

5

在C++ 11使用std::minstd::max的办法是采取initializer_list

int Sum(std::initializer_list<int>); 

这是合适的,当所有的参数应该是相同的类型。你会称其为Sum({ 1, 2, 3, 4})

+0

有趣。需要在VS2010上使用我的解决方案时,我忘记了即将推出的初始化列表功能。实际上,这就是C++ 11的方式,感谢您的贡献! – 2013-03-05 12:58:55