2016-05-16 98 views
7

所以如果我有這樣的事情重載輸出運算符<<一類打印裏面的元組

template<typename... Args > 
class tuple_class 
{ 
    public: 
    std::tuple<Args...> tup; 

/*I left out the other functions */ 
}; 

我想重載操作< <,這樣它會遞歸打印元組時呼籲班上。

ex。

auto a = tuple_class(1, 2 ,3); 
std::cout << a << endl; 

將有希望打印「123」

我見過的元組打印機的其它例子,但我不能,而無需一堆麻煩把它應用到我的課

我想我應該開始成員函數這樣

template<typename... Args> 
    friend std::ostream& operator<<(std::ostream& os, const my_tuple<Args...> &m); 

,然後將類外的實際功能

template<typename... Args> 
std::ostream& operator<<(std::ostream& os, const my_tuple<Args...> &m) 
{ 
    os << "SOMETHING" << std::endl; 
    return os; 
} 

實際上,當我在我的班級撥打< <運營商時,它確實有效。但我不知道如何使它實際打印元組。

任何幫助,將不勝感激

+1

您需要通過部分特化遞歸展開可變參數模板。見[這個問題](http://stackoverflow.com/questions/7124969/recursive-variadic-template-to-print-out-the-contents-of-a-parameter-pack)。 – denniskb

回答

2

要構建解決方案,我用的元組打印代碼從這裏this提到cppreference。其餘的代碼是粘合在一起的。 Here我把工作樣本。

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

// tuple printer 
template<class Tuple, std::size_t N> 
struct TuplePrinter { 
    static std::ostream& print(std::ostream& os, const Tuple& t) 
    { 
     TuplePrinter<Tuple, N - 1>::print(os, t); 
     os << ", " << std::get<N - 1>(t); 
     return os; 
    } 
}; 

template<class Tuple> 
struct TuplePrinter<Tuple, 1> { 
    static std::ostream& print(std::ostream& os, const Tuple& t) 
    { 
     os << std::get<0>(t); 
     return os; 
    } 
}; 

template<class... Args> 
std::ostream& print(std::ostream& os, const std::tuple<Args...>& t) 
{ 
    os << "("; 
    TuplePrinter<decltype(t), sizeof...(Args)>::print(os, t); 
    os << ")\n"; 
    return os; 
} 


// class to keep tuple inside 
template<typename... Args> 
class tuple_class { 
    template<typename... Args2> 
    friend std::ostream& operator<<(std::ostream& os, const tuple_class<Args2...> &m); 

    std::tuple<Args...> tup; 
public: 
    tuple_class(Args&&... args) : tup(std::forward<Args>(args)...) { 

    } 
}; 

// usage of the printer 
template<typename... Args> 
std::ostream& operator<<(std::ostream& os, const tuple_class<Args...> &m) { 
    print(os, m.tup); 
    return os; 
} 



int main() { 
    tuple_class<int,float,std::string> tc(1,3.0f,"string"); 
    std::cout << tc; 
    return 0; 
} 
+0

感謝您的回覆,當我嘗試這個我得到2錯誤:錯誤:無法綁定'std :: ostream {aka std :: basic_ostream }'左值爲'std :: basic_ostream &&'os << std::get<0>(t);和錯誤:'operator <<'不匹配(操作數類型是'std :: ostream {aka std :: basic_ostream }'和'std :: __ tuple_element_t <0ul, – user2770808

+0

你能否給我提供你的確切版本的編譯器,編譯器標誌你,被使用? – tomekpe

+0

我修正了它與我構建元組的方式有關,謝謝! – user2770808

0

如果你可以做到沒有標準元組,我建議以下簡單的(我希望如此)解決方案。

#include <iostream> 

template <typename ... Args > 
class my_tuple; 

template <typename A0, typename ... Args > 
class my_tuple<A0, Args...> 
{ 
    private: 

     A0     elem; 
     my_tuple<Args...> next; 

    public: 

     my_tuple (const A0 & a0, const Args & ... args) 
     : elem { a0 }, next { args ... } 
     { } 

     /*I left out the other functions */ 

     friend std::ostream& operator<< (std::ostream & os, 
             const my_tuple<A0, Args...> & m) 
     { return os << m.elem << m.next; } 
}; 

template <> 
class my_tuple<> 
{ 
    public: 

     friend std::ostream& operator<< (std::ostream & os, 
             const my_tuple<> &) 
     { return os; } 
}; 

int main() 
{ 
    my_tuple<int, float, long> mt1 { 12, 23.4, 45L }; 
    my_tuple<int, int, int>  mt2 { 1, 2, 3 }; 

    std::cout << "my tuple 1 [" << mt1 << ']' << std::endl; 
    std::cout << "my tuple 2 [" << mt2 << ']' << std::endl; 

    return 0; 
}