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;
};

我想operator()根据模板参数构造不同的行为N。的行为N=3在上面的代码中进行了描述。假设sizeof...(dat) >= N.

我尝试了一段时间。但我没能做到。请给我一些建议。:)

4

2 回答 2

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);
}
于 2013-05-29T13:57:19.040 回答
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);
    }
};

更新

我更新了我的代码以说明您一般如何完成它。

于 2013-05-29T13:45:54.320 回答