Is there a way to use the Named Constructor Idiom with templates in a "pretty" fashion?
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'd like to use the syntax of #1
somehow. #2
works but rubs my DRY sense the wrong way.
EDIT: New, more "realistic" version of Foo
.
EDIT2: No C++0x/C++1x for me I'm afraid :(
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;
}
};
This then compiles:
int main( int argc, char** argv )
{
vector<double> vec;
vec.push_back(1);
Foo<vector<double>> a_foo = FooHelper::HalfSize( vec );
}
I don't think there is a DRY problem, think of it as a language restriction. If you have a Class Foo without template but you want to create a new object from a static method, you'd have to do something like:
Foo a_foo = Foo::HalfSize(something);
and there's of course the Foo repeated twice.
So, since here the full Class name is Foo< vector<double> >
, it's logical to get the static method from Foo< vector<double> >::HalfSize()
, since that's the C++ way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With