【问题标题】:C++ template function with unknown number of arguments具有未知数量参数的 C++ 模板函数
【发布时间】:2010-07-22 10:42:37
【问题描述】:

这可能是一个无用的问题,但它在我的脑海中停留了几个小时。

我想编写一个函数,它接受一些(POD)参数,将它们转换为字符串并返回连接。例如

template<typename A, typename B>
string ToString(A a, B b)
{
    stringstream ss;
    ss << a << b;
    return ss.str();
}

很简单,对吧? 但是当我想用 unknown 数量的参数编写相同的函数时,它变得非常困难(当然对我来说)。

有可能吗?有什么解决办法吗?

【问题讨论】:

    标签: c++ templates function


    【解决方案1】:

    在 C++03 中,没有。您所能做的就是创建具有不同数量参数的重载:

    template<typename A, typename B>
    string ToString(A a, B b)
    {
        stringstream ss;
        ss << a << b;
        return ss.str();
    }
    
    template<typename A, typename B, typename C>
    string ToString(A a, B b, C c)
    {
        stringstream ss;
        ss << a << b << c;
        return ss.str();
    }
    

    这可以通过 Boost.Preprocessor 库(在某种程度上)自动化。

    在 C++0x 中,您可以像这样使用可变参数模板:

    #include <iostream>
    
    void f()
    {
    }
    
    template <class T, class ... Ts>
    void f(const T& a, const Ts&... args)
    {
      std::cout << a;
      f(args...);
    }
    

    【讨论】:

    • 这是正确的。只有在带有可变参数模板的 C++0x 中才能真正做到这一点。
    【解决方案2】:

    几乎像真的一样:-)

    #include <iostream>
    #include <string>
    #include <sstream>
    using namespace std;
    
    template<class L,class R>
    struct cons_t
    {
        const L &l; const R &r;
        cons_t(const L &_l, const R &_r) : l(_l),r(_r) {}
    };
    template<>
    struct cons_t<void,void>{};
    typedef cons_t<void,void> cons;
    
    template<class L,class R,class A>
    cons_t< cons_t<L,R>, A> operator , (const cons_t<L,R> &l, const A &arg)
    {
        return cons_t< cons_t<L,R>, A>(l,arg);
    }
    void to_stream(stringstream &s, const cons_t<void,void> &) { }
    template<typename L, typename R>
    void to_stream(stringstream &s, const cons_t<L,R> &c)
    {
        to_stream(s, c.l); 
        s << c.r;
    }
    template<typename L, typename R>
    string to_string(const cons_t<L,R> &c)
    {
        stringstream ss;
        to_stream(ss,c);
        return ss.str();
    }
    
    #define ToString(...) to_string((cons(),__VA_ARGS__))
    int main()
    {
        cout << ToString(1,2,"Hi There",3.14159);
    }
    

    【讨论】:

      【解决方案3】:

      我知道这可能是一个学术问题,因此解决方案可能不是您想要的。

      但是。

      在现实生活中处理此问题的一种简单方法是传入对象的列表或数组,而不是具有多个参数。
      你知道,比如 Main()

      【讨论】:

      • hhhmmm,我不确定你所说的列表或数组。是否可以制作一个接受任何类型的数据的列表?我知道 C# 可能一切都是 object 但 C++ 呢?
      • 你可以使用空指针。然后,您必须将其转换为方法内部可用的东西,并进行一些检查以获取其类型。或者根据您的应用程序,您可以为您希望传入的类放入一个超类。例如
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-25
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      相关资源
      最近更新 更多