2015-10-31 3 views
3

Я пробуя код из http://florianjw.de/en/variadic_templates.html:VARIADIC шаблоны дают ошибки на более чем одного параметра

#include <tuple> 
#include <initializer_list> 
#include <iostream> 
#include <string> 

template<typename Fun, typename...Ts> 
void sequential_foreach(Fun f, const Ts&... args) { 
    (void) std::initializer_list<int>{ 
    [&](const auto& arg){f(arg); return 0;}(args)... 
    }; 
} 

template<typename...Ts> 
void print_all(std::ostream& stream, const Ts&... args) { 
    sequential_foreach([&](const auto& arg){stream << arg;}, args...); 
} 

int main() 
{ 
    std::string s1("string1"); 
    std::string s2("string2"); 
    print_all(std::cout, s1, s2); 

    return 0; 
} 

Но я получаю следующие ошибки: (когда я прохожу более одного параметра к print_all)

main.cpp: In instantiation of ‘void sequential_foreach(Fun, const Ts& ...) [with Fun = print_all(std::ostream&, const Ts& ...) [with Ts = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >}; std::ostream = std::basic_ostream<char>]::<lambda(const auto:2&)>; Ts = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >}]’: 
main.cpp:14:67: required from ‘void print_all(std::ostream&, const Ts& ...) [with Ts = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >}; std::ostream = std::basic_ostream<char>]’ 
main.cpp:21:30: required from here 
main.cpp:8:5: error: uninitialized const member ‘sequential_foreach(Fun, const Ts& ...) [with Fun = print_all(std::ostream&, const Ts& ...) [with Ts = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >}; std::ostream = std::basic_ostream<char>]::<lambda(const auto:2&)>; Ts = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >}]::<lambda(const auto:1&)>::<f capture>’ 
    [&](const auto& arg){f(arg); return 0;}(args)... 
    ^

Что я делаю неправильно? ideone ссылка: https://ideone.com/

Я попытался с ideone (gcc5.1 c++14) и на Redhat 6 gcc version 4.9.1 20140922 (Red Hat 4.9.1-10)

+1

Он отлично компилируется в Visual Studio и последней Clang очевидно. Вы намеренно не указали ? http://coliru.stacked-crooked.com/a/aafca0fdb174287f – DeiDei

+1

@DeiDei О'кей, я плохо с '#include ', но все же он не компилируется ни на моей машине, ни на идеоне. – Patryk

+0

Единственное, что я могу заметить, это то, что лямбда 'print_all' должна быть сделана' mutable' (поскольку по умолчанию lambda является const, которая также делает захваченный поток const, который не должен работать; * я не знаю, имеет ли ссылки разные правила *). Кроме этого, я не вижу никаких проблем. Однако вы сделали свой код излишне сложным. Посмотрите, как я [упростил это] (https://ideone.com/eIejtW). – Nawaz

ответ

1

Как T.C. не разместил это как ответ я отправляю его здесь, так что каждый может найти его.

ideone link

#include <tuple> 
#include <initializer_list> 
#include <iostream> 
#include <string> 
#include <vector> 

template<typename Fun, typename...Ts> 
void sequential_foreach(Fun f, const Ts&... args) { 
    auto fun = [&](const auto& arg){f(arg); return 0;}; 
    (void) std::initializer_list<int>{ fun(args)... }; 
} 

template<typename...Ts> 
void print_all(std::ostream& stream, const Ts&... args) { 
    sequential_foreach(
     [&](const auto& arg){stream << arg;}, 
     args... 
    ); 
} 

int main() 
{ 
    std::string s1("string1"); 
    std::string s2("string2"); 
    print_all(std::cout, s1, s2); 

    return 0; 
} 
Смежные вопросы