NewObj use on template with several typename.

On 09/03/2016 at 15:38, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R17 
Platform:      Mac OSX  ; 
Language(s) :     C++  ;

---------
hi,
I'm not sure if we can call that a bug or if it's problem with my syntax.

i've defined a class using template with several typename. NewObj doesn't want those templates.
i've got the message "parse issue"
: Expected '>'
: Type name requires a specifier or qualifier

a very simplified class :

template <typename T, typename T2>
class myclass
{
public:
    T toto;
    T2 tata;
    myclass();
    ~myclass();
};
template <typename T, typename T2> myclass<T, T2>::myclass() {  }
template <typename T, typename T2> myclass<T, T2>::~myclass(){  }
  
  
//somewhere else
  
// got the error message
 myclass<Int32, Vector>* titi = NewObj(myclass<Int32, Vector>); 

the following code generate error :
: Too many arguments provided to function-like macro invocation
: Use of undeclared identifier 'SIZEOF'

Int theSize = SIZEOF(myclass<Int32, Vector>);

but the following compile with no errors (but i know it's not a clean solution) :

myclass<Int32, Vector>* toto = MAXON_SAFE_PLACEMENT_NEW(maxon::DefaultAllocator::Alloc((maxon::Int)sizeof(myclass<Int32, Vector>), C4D_MISC_ALLOC_LOCATION)) myclass<Int32, Vector>(); 

It does work if myclass only got one typename.

Thanks a lot.

On 10/03/2016 at 04:06, xxxxxxxx wrote:

Hey Valkaari, this is a known problem with macros. The comma in the template arguments is used as
separator for the macro arguments instead. This answer from SO might help you:

http://stackoverflow.com/a/4298441/791713

Basically, you build another macro that wraps the type for you, like this:

template<typename T> struct get_first_param;
template<typename R, typename P1> struct get_first_param<R(P1)> {
  typedef P1 type;
};
#define Identity(...) get_first_param<void(__VA_ARGS__)>::type
  
// Then to use NewObj() :
myclass<Int32, Vector>* obj = NewObj(Identity(myclass<Int32, Vector>));

On 10/03/2016 at 06:21, xxxxxxxx wrote:

Hi,

As specified on the stackoverflow thread, the type wrapper is useful because it works with previous C++11 standard where variadics arguments in macro weren't introduced yet.
If you can use __VA_ARGS__ then this should works:

#define FIX_ARG(...) __VA_ARGS__
myclass<Int32, Vector>* tata = NewObj(FIX_ARG(myclass<Int32, Vector>));

or (worst) :

#ifdef SIZEOF 
    #undef SIZEOF 
#endif 
#define SIZEOF(x...) ((maxon::Int)sizeof(x)) 
  
#define COMMA , 
  
myclass<Int32, Vector>* tata = NewObj(myclass<Int32 COMMA Vector>); 

On 10/03/2016 at 09:24, xxxxxxxx wrote:

Hello,

it seems that using a typedef may also help:

  
typedef myclass<Int32, Vector> IntVectorClass;  
  
IntVectorClass* intVector = NewObj(IntVectorClass);  

best wishes,
Sebastian

On 11/03/2016 at 02:26, xxxxxxxx wrote:

Thanks for the answers, several solutions, i like it :)
And more important i think i understood all the solutions.