2013-05-29 23 views
0

我想建造像,通用打印機與非類型模板參數

template<class Ostream, int N> 
class StreamPrinter{ 
public: 
    StreamPrinter(Ostream& out, std::string tail = "\n", std::string head = "", std::string middle = "\t") 
    : out(out) 
    , tail(tail) 
    , head(head) {} 


    template<class... Data> 
    void operator()(const Data&... dat){ 
     //if N = 3, 
     //out << head << dat1 << middle << dat2 << middle << dat3 << tail; 
     //where dat# means the #'s argument of dat... 
    } 

private: 
    Ostream& out; 
    std::string tail; 
    std::string head; 
    std::string middle; 
}; 

我想建造其行爲不同,這取決於模板參數Noperator()。 上述代碼描述了N=3的行爲。假設sizeof...(dat) >= N

我試了一段時間。但我未能實現。請給我一些建議。:)

+0

如果'operator()'的參數個數與'N'不相同怎麼辦? – aschepler

+0

參數個數可以大於'N'。剩下的參數將不會被打印。 – Sungmin

回答

3
#include <string> 
#include <iostream> 

template<class Ostream, int N> 
class StreamPrinter{ 
public: 
    StreamPrinter(Ostream& out, 
        std::string tail = "\n", 
        std::string head = "", 
        std::string middle = "\t") 
    : out(out) 
    , tail(tail) 
    , head(head) {} 


    template<class... Data> 
    void operator()(const Data&... dat) 
    { 
     static_assert(sizeof...(Data) >= N, 
         "Not enough arguments supplied for `operator()`"); 

     out << head; 
     print(N, dat...); 
     out << tail; 
    } 

private: 
    void print(int) {} 

    template<class D, class... Data> 
    void print(int printed, D const& p, Data const&... pp) 
    { 
     if(0 == printed) { return; } 

     out << p; 
     if(sizeof...(Data) > 0) 
     { 
      out << middle; 
      print(printed-1, pp...); 
     } 
    } 

    Ostream& out; 
    std::string tail; 
    std::string head; 
    std::string middle; 
}; 


int main() 
{ 
    StreamPrinter<std::ostream, 4> foo(std::cout); 
    foo(1,2,3,4,5,6); 
} 
+0

這很完美。謝謝:) – Sungmin

+0

@Sungmin那麼它不需要> = N參數,但可以通過'static_assert'在'operator()'中檢查。 – dyp

+0

謝謝。我知道了。您可以在答案中添加static_assert部分以確保完整性? – Sungmin

1

你可以委託給具有專門的N

template<int N> 
struct StreamHelper { 

    template< 
     typename OS, 
     class... Data, 
     class = typename std::enable_if< std::is_same< std::integral_constant<int,N>, std::integral_constant<int,sizeof...(Data)> >::value >::type > 
    void apply(
     OS& os, 
     const std::string& head, 
     const std::string& mid, 
     const std::string& tail, 
     const Data&... dat) 
    { 
     os << head; 
     apply_impl(os, mid, tail, dat); 
    } 

private: 
    template<typename OS> 
    void apply_impl(
     OS& os, 
     const std::string& mid, 
     const std::string& tail) 
    { 
     os << tail; 
    } 

    template<typename OS, class D0, class... D> 
    void apply_impl(
     OS& os, 
     const std::string& mid, 
     const std::string& tail, 
     const D0& d0, 
     const D&... d) 
    { 
     os << d0 << mid; 
     apply_impl(os, mid, tail, d); 
    } 
}; 

更新的輔助結構

我更新了我的代碼來說明如何可能一般完成它。

+0

那麼,是不是有一種通用的方式來實現我上面描述的功能,而沒有專門針對某些'N'? – Sungmin

+0

我實際上無法理解'N'如何在您的代碼中執行::( – Sungmin

+0

更新爲enable_if –