I wanted to use the C++11 auto little specifier to deduce my return type , but the example in which i am trying to use it is a little different than its typical use.
I have a base class , and subclasses that derive certain member functions.
enum class state {composite1, composite2, composite3};
class material
{
public:
}
class sub_material1 : material
{
public:
template<typename T>
T* transform(state to_state)
{
T* material;
switch(to_state){
case(state::composite1) :
//do transform computations
// set material to return
material = some_transformed_material;
break;
case(state::composite2):
// do transform computation
// set material to return
material = some_transformed_material;
break;
.
.
.
.
}
return material;
}
}
so if i had something like
sub_material1 mat1;
sub_material2 mat2;
mat2 = mat1.transform(state::composite2);
how can i use auto and decltype in this case given the fact that i have condition to test that can be very lengthy....decltype seems an overkill ?
How can the type be inferred ?
Thank you
This code will not work. Compiler can't deduce template argument based on return type, so you should set in manually:
auto mat2 = mat1.transform<sub_material2>(state::composite2);
if mat2 was declared before:
sub_material2 *mat2;
mat2 = mat1.transform<sub_material2>(state::composite2);
You are trying to mix pointer and non pointer type.
I suggest you to try the following:
struct composite1 {};
struct composite2 {};
struct composite3 {};
class material
{
public:
}
class sub_material1 : material
{
public:
sub_material1 transform(composite1)
{
//do transform computations
// set material to return
return some_transformed_material;
}
sub_material2 transform(composite2)
{
//do transform computations
// set material to return
return some_transformed_material;
}
.
.
.
.
}
then you can something like this:
sub_material1 mat1;
auto mat2 = mat1.transform(composite2{});
or
sub_material1 mat1;
sub_material2 mat2;
mat2 = mat1.transform(composite2{});
You can return pointer if you like, but then mat2 should by of type sub_material2*.
If what you want is also the following:
sub_material3 ma3 ;
mat3 = mat1.transform(state::composite3)
then the answer is: you can't. The compiler has to know at compile time which version of transform to call. You can do something like this:
template <enum class state>
struct state_material
{
typedef type sub_material1 ;
} ;
and then specialize
template <>
struct state_material<state::composite1>
{
typedef type sub_material1 ;
} ;
template <>
struct state_material<state::composite2>
{
typedef type sub_material2 ;
} ;
template <>
struct state_material<state::composite3>
{
typedef type sub_material3 ;
} ;
Then call like this:
mat2 = mat1.template transform<state_material<state::composite2>::type>()
The code in its current form won't work at all, and neither auto
nor decltype
are going to help much here. The compiler can't infere what the actual type of T is. So you would have to specify what that type is when calling transform
:
mat2 = mat1.transform<sub_material2>(state::composite2);
However, there is still a problem: transform
returns a T*
, not a T
, ie the assignment won't work unless you declared mat2
to be of type sub_material2*
.
If the method could return different types of materials based on a runtime parameter, you would have to eg return a pointer to an object of the base class material
. Templates are for making compile-time decisions, but your method looks like it makes a runtime decision!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.