2016-10-18 7 views
0

Я пишу кучу функций, как это:Упрощая работа с переменным числом функций/макросов

template <> 
Error SyntaxError<unfinished_string>(unsigned int line) { 
    std::stringstream message; 
    message << "SyntaxError: unfinished string (starting at line " << line << ")."; 
    return Error(Error::Type::syntax, message.str()); 
} 

template <> 
Error SyntaxError<malformed_number>(std::string number, unsigned int line) { 
    std::stringstream message; 
    message << "SyntaxError: malformed number (" << number << ") at line " << line << '.'; 
    return Error(Error::Type::Syntax, message.str()); 
} 

... 

И это не было бы плохо иметь VARIADIC функцию/макрос, который выглядел примерно так:

Error proto(/*variable number & type of arguments*/) { 
    std::stringstream message; 
    message << "SyntaxError: " << /*arguments passed, separated by <<s */; 
    return Error(Error::Type::syntax, message.str()); 
} 

Так что я мог бы написать свои функции как:

template <> 
Error SyntaxError<unfinished_string>(unsigned int line) { 
    return proto("unfinished string (starting at line ", line, ")."); 
} 

template <> 
Error SyntaxError<malformed_number>(std::string number, unsigned int line) { 
    return proto("malformed number (", number, ") at line ", line, '.'); 
} 

Это случайно не возможно? Как, если да?

+0

Не знаете, почему люди голосуют, чтобы закрыть. Ответ - да. Через секунду я соберу реальный ответ. – xaxxon

+0

Сколько версий вам нужно? Можете ли вы добавить дополнительные конструкторы в 'Error'? Подобно ['std :: system_error'] (http://en.cppreference.com/w/cpp/error/system_error/system_error). –

ответ

1

Если вы хотите преобразовать вариационный список аргументов и полностью потопить их, тогда вы можете реализовать дополнительную функцию, которая рекурсивно добавляет каждый аргумент к этому потоку. Пример:

template< typename FirstArg, typename... Args > 
inline std::ostream& join_args(std::ostream& os, FirstArg arg, Args... args) { 
    os << arg; 
    return join_args(os, args...); 
} 

Шаг за шагом, вы будете исчерпав аргументы. Соблюдайте порядок, который вы обрабатываете, (std::ostream& os, FirstArg arg, Args... args) - это не то же самое, что и (std::ostream& os, Args... args, LastArg arg).

И последнее, но не в последнюю очередь, вы должны охватывать случаи угловые (либо один или нет аргументов, в зависимости от вашей проблемы):

inline std::ostream& join_args(std::ostream& os) { 
    return os; 
} 

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

+1

'return join_args (args ...);' не следует передавать 'os' в качестве первого аргумента (т. Е.' Join_args (os, args ...) ')? – user6245072

+0

Это работает как шарм! Спасибо огромное! – user6245072

+0

Определенно user6245072, я только что закодировал его и забыл просмотреть эти ошибки. Благодаря! –

 Смежные вопросы

  • Нет связанных вопросов^_^