Как сформировать строку с использованием шаблонов variadi c без рекурсии в c ++ 11 - PullRequest
0 голосов
/ 14 апреля 2020
template <typename ...Args>
void logImpl(tloglevel level, Args&& ...args)
{
    ostringstream stream;
    (stream << ... << std::forward<Args>(args)) << '\n';
    syslog(level, stream.str());
}

func A()
{
int a =10;
std::string b = "test";
logImpl(LOG_INFO, "printing",a,b);
}

func B()
{
unsigned long t = 6700;
logImpl(LOG_INFO, t);
}

Я понимаю, что мы можем добиться этого, используя шаблоны c variadi. Но возможно ли это сделать без рекурсии? складное выражение не является опцией, так как поддерживается только c ++ 11. Пожалуйста, дайте мне знать, если у кого-то есть идея лучше использовать шаблоны variadi c без рекурсии или сгиба. Я хочу сделать это в C ++ 11.

1 Ответ

1 голос
/ 14 апреля 2020

Вам не нужно использовать рекурсию для этой работы.

Вы можете создать поддельный массив с расширяющимся пакетом параметров при его заполнении:

template<class ... Args>
std::string makeString(Args...args){
    std::string s;
    int temp[] = { (s += toString(args),0)... }; // concatenation
    static_cast<void>(temp);
    return s;
}

для toString, который вы предоставляете перегрузки для обработки всех типов, которые вы хотите.

Например:

template<class T>
std::string toString(T t){
    return std::to_string(t);   // for numbers 
}

std::string toString(const std::string& str){
    return str;
}

std::string toString(const char* str){
    return str;
}

Полная демонстрация


Хм, вы даже не используйте toString, версия с ostringstream:

template<class ... Args>
std::string makeString(Args&&...args){
    std::ostringstream os;
    int temp[] = { ((os << std::forward<Args>(args)),0)... };
    static_cast<void>(temp);
    return os.str();
}
...