Named design idioms and patterns?

Is there a way to use the Idiom Named Constructor with templates in a “pretty” way?

For instance:

#include <vector>
using namespace std;

template< typename T >
class Foo
{
public:
    static Foo Copy(const T& arg)
    {
        Foo ret;
        ret.t_copy = arg;
        return ret;
    }

    static Foo CopyClear(const T& arg)
    {
        Foo ret;
        ret.t_copy = arg;
        ret.t_copy.clear();
        return ret;
    }

private:
    T t_copy;
};


int main( int argc, char** argv )
{
    vector<double> vec;
    vec.push_back(1);

    // #1: won't compile
    Foo< vector<double> > a_foo = Foo::CopyClear( vec );

    // #2: ugly, but works
    Foo< vector<double> > a_foo = Foo< vector<double> >::CopyClear( vec );

    return 0;
}

I would like to use the syntax somehow #1. #2works, but rubs my DRY in the wrong way.

EDIT: A new, more "realistic" version Foo.

EDIT2: No C ++ 0x / C ++ 1x for me, I'm afraid :(

+5
source share
6 answers

Updated Answer

If I understand your intent correctly, this will do the trick:

template< typename T >
class Foo
{
private:
    friend class FooHelper;
    size_t sz;
};

class FooHelper
{
public:
    template< typename T >
    static Foo<T> Size(const T& arg)
    {
        Foo<T> ret;
        ret.sz = arg.size();
        return ret;
    }

    template< typename T >
    static Foo<T> HalfSize(const T& arg)
    {
        Foo<T> ret;
        ret.sz = arg.size() / 2;
        return ret;
    }
};

Then compiles:

int main( int argc, char** argv )
{
    vector<double> vec;
    vec.push_back(1);

    Foo<vector<double>> a_foo = FooHelper::HalfSize( vec );
}
+3
source

, , . Foo , , - :

Foo a_foo = Foo::HalfSize(something);

, , Foo .

, Foo< vector<double> >, Foo< vector<double> >::HalfSize(), ++.

+3

@Jon . std::make_pair std::pair, .

+3

, , :

    Foo< vector<double> > a_foo = a_foo.CopyClear( vec );

, CopyClear - - static.

, . typedef. - static , . - , -.

, ; , (), , .

, CopyClear, ? , .

, , ?

, .

hth.,

+3

If you can use C ++ 0x functions, the keyword autowill help. Is there a reason why Size()they HalfSize()should be static methods? If you provide methods for mutate sz, you can do this:

template<class T>
Foo<T> HalfSize(const T& arg)
{
    Foo<T> ret;
    ret.setSz(arg.size() / 2); // or similar
    return ret;
}

and then # 1 is a little more achievable.

+2
source

C ++ 1x to the rescue:

auto a_foo = Foo::HalfSize<vector<double>>( vec );

And, yes, two closures are >>parsed as > >in C ++ 1x.

You may already have a compiler near you.

+2
source

All Articles