Шаблонная функция C ++ с неизвестным количеством аргументов - PullRequest
2 голосов
/ 22 июля 2010

это, вероятно, бесполезная проблема, но она застряла у меня на несколько часов.

Я хочу написать функцию, которая принимает некоторые (POD) аргументы, конвертирует их в строку и возвращает конкатенацию. например

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

довольно легко, а? но это довольно сложно (для меня, конечно), когда я хочу написать ту же функцию с неизвестным числом аргументов.

это вообще возможно? любое решение?

Ответы [ 3 ]

9 голосов
/ 22 июля 2010

В 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...);
}
5 голосов
/ 22 июля 2010

Почти как настоящая вещь: -)

#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);
}
1 голос
/ 22 июля 2010

Я знаю, что это, вероятно, академическая проблема, и поэтому обходное решение, вероятно, не то, что вы хотите.

Но.

Простой способ справиться с этим в реальной жизни будетпередавать список или массив объектов, а не иметь несколько параметров.
Знаете, как Main ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...