Sign in to follow this  
Toni Petrina

How to manually create template member function

Recommended Posts

If class was defined as
class Anyclass {
public:
  template <class T> T&GetObject()
  {
    return new T;
  }
};
and I want to do this
AnyClass factory;
SomeOtherClass object = factory.GetObject();
This, unfortunately doesn't work. I've tried following
factory.GetObject<SomeOtherClass>()
but same error comes.
Cannot deduce template argument for 'bla bla'
Anyone knows solution to this problem.

Share this post


Link to post
Share on other sites

#include <string>
#include <iostream>

class Factory
{
public:
template <typename T> T* make(){ return new T();}
};

class A
{
public:
void foo(){ std::cout << "A::foo()" << std::endl;}
};

int main()
{
Factory f;

f.make<int>();
f.make<std::string>();
f.make<A>()->foo();
}




works without problems using VC7.1

edit:

without problems as in compiles and dutifully leaks memory.

Share this post


Link to post
Share on other sites
The only problem that i can see with the code is that the expression new T returns type T*, not T, so your return type is wrong on the function (should be T*, not T&), or return *new T; inside the function if you prefer. Apart from that, it should compile, the factory.GetObject<SomeOtherClass>() version that is, though looks like a likely source for a leak if not used wisely.

Share this post


Link to post
Share on other sites
Quote:
Original post by Jingo
The only problem that i can see with the code is that the expression new T returns type T*, not T, so your return type is wrong on the function (should be T*, not T&), or return *new T; inside the function if you prefer. Apart from that, it should compile, the factory.GetObject<SomeOtherClass>() version that is, though looks like a likely source for a leak if not used wisely.


It was just an example. True code is for property list which accepts any type and returns any type.

BTW, I'm on VC++6.0

Share this post


Link to post
Share on other sites
Short of the actual code that gives the error, I would have to conclude that it's due the poor template support in VC6. DigitalDelusion's code gives 5 errors in vc6, so it likely is the compiler. You can get the 2003.net pro compiler free from msdn, I'm sure it wont be too difficult to hook it up to the vc6 IDE.

Share this post


Link to post
Share on other sites
I don't have VC6 close but I belive this would work even with its broken template support

#include <iostream>

class Factory
{
public:
template <typename T> void make(T*& p){ p = new T();}
};

class A
{
public:
void foo(){ std::cout << "A::foo()" << std::endl;}
};

int main()
{
Factory f;
A *pA;

f.make( pA);
pA->foo();

}

Share this post


Link to post
Share on other sites
Quote:
Original post by DigitalDelusion
*** Source Snippet Removed ***

works without problems using VC7.1

edit:

without problems as in compiles and dutifully leaks memory.

Well, it doesn't work.
D:\Cyprox Studios\The King Of Gods\QuickCode\main.cpp(358) : error C2062: type 'int' unexpected
D:\Cyprox Studios\The King Of Gods\QuickCode\main.cpp(359) : error C2275: 'std::string' : illegal use of this type as an expression
D:\Cyprox Studios\The King Of Gods\QuickCode\main.cpp(359) : error C2059: syntax error : ')'
D:\Cyprox Studios\The King Of Gods\QuickCode\main.cpp(360) : error C2275: 'A' : illegal use of this type as an expression
D:\Cyprox Studios\The King Of Gods\QuickCode\main.cpp(348) : see declaration of 'A'
D:\Cyprox Studios\The King Of Gods\QuickCode\main.cpp(360) : error C2059: syntax error : ')'

Well, that's just it. Compiler is broken.

Anyway, I've come to somewhat esoteric solution.
template <class T> struct TType {};

class Factory
{
public:
template <typename T> T* make(TType<T>){ return new T();}
};

class A
{
public:
void foo(){ std::cout << "A::foo()" << std::endl;}
};


int main()
{
Factory f;

f.make(TType<int>());
f.make(TType<std::string>());
f.make(TType<A>())->foo();
return 0;
}

It compiles fine and doesn't produce trash. Here is the assembly (debug).
; 358  : 	Factory f;
; 359 :
; 360 : f.make(TType<int>());

mov al, BYTE PTR $T93490[ebp]
push eax
lea ecx, DWORD PTR _f$[ebp]
call ?make@Factory@@QAEPAHU?$TType@H@@@Z ; Factory::make

Share this post


Link to post
Share on other sites
Quote:
Original post by DigitalDelusion
I don't have VC6 close but I belive this would work even with its broken template support
*** Source Snippet Removed ***


But my intention was to return reference to object so I could write
Class &property = list.getProperty("some")
in any form available

Edit: sorry

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this