C++ 可变参数——我使用它们的方式好还是不好?有好的选择吗?

标签 c++ visual-studio-2010 c++11 variadic-functions

这样做的最终目标是拥有一个函数,该函数可以接受特定类型(相同类型,而不是不同类型)的可变数量的参数,这些参数可以在函数调用时声明。

因为我使用的是 Visual Studio 2010,所以我不能:

MyFunction({1,2,3});

在之前回答的问题中,我发现我可以使用 boost::assign::list_of(),但是后来我发现这个 seems to have a bug of some kind如果您尝试只向它传递一个参数。

所以我做了更多搜索,发现我可以使用可变参数函数来实现我的目标。

void TestFunction2<int>(int count, ...)
{}

但是,我想按类型限制它,所以最终发现我可以使用模板来做到这一点:

template <class T>
void TestFunction(const T& count, ...);

template <>
void TestFunction<int>(const int& count, ...);

不幸的是,va_list 之类的可变参数显然不喜欢引用。我看到的限制类型的示例使用了 const 引用。如果我删除 count 参数的 const 引用方面,它会按我想要的方式工作,但我不知道这是否会导致可怕的副作用,或者这整个 varargs 事情是否是一个坏主意开始于。

所以我想我的问题是,我在上面最后一个示例中所做的是好是坏?如果它不好,什么是好的替代方案,这样我就可以调用一个带有一个或多个内联参数的函数,比如 int 参数?

最佳答案

你要的是std::initializer_list<T> ,不幸的是,这需要 C++11 支持。

另一种选择,几乎同样优雅且易于升级,is to use an array :

#include <iostream>
 
template <typename T, size_t N>
void func(T (&s)[N]) {
    for (size_t i = 0; i != N; ++i) {
        std::cout << s[i] << '\n';
    }
}
 
int main() {
    int array[] = {1, 2, 3};
    func(array);
}

当您转向支持初始化列表的编译器时,this can be changed into :

#include <iostream>
 
template <typename T>
void func(std::initializer_list<T> s) {
    for (T const& t: s) {
        std::cout << t << '\n';
    }
}
 
int main() {
    func({1, 2, 3});
}

因此函数和调用站点的更新都将是无痛的。

注意:可以使用宏使调用站点完全相似,我建议不要使用这种方法,声称的 yield 不值得混淆。

关于C++ 可变参数——我使用它们的方式好还是不好?有好的选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18376969/

相关文章:

c++ - 如何使用 std :from_chars 在 C++17 中从字符串转换为 int/float

c++ - ofVideoPlayer 中没有名为 idleMovie 的成员

c++ - 如何将管道作为文件传递给 C 应用程序?

c++ - 未解析的符号:sql::mysql::get_driver_instance(void)

asp.net-mvc - 有没有办法使用符号服务器调试 ASP.NET MVC 代码(而不是下载源代码并引用它)?

c++ - 如果 nullptr_t 不是关键字,为什么是 char16_t 和 char32_t?

c++ - 包裹在 lambda 中的 lambda 的效率是多少?

c++ - C++ STL 容器中的多态性

c++ - 为什么无法通过 Call-by-Value 将 mutex 传递给 function?

c++ - 用于 Visual Studio 2010 的 C++ 内存泄漏工具