类模板化成员函数和返回类型推断

时间:2015-08-05 06:56:36

标签: c++ templates c++11

我想使用C ++ 11自动小指示符来推断我的返回类型,但是我尝试使用它的示例与它的典型用法略有不同。

我有一个基类,以及派生某些成员函数的子类。

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;
}
}

所以,如果我有像

这样的东西
sub_material1 mat1;
sub_material2 mat2;

mat2 = mat1.transform(state::composite2);

在这种情况下我如何使用auto和decltype,因为我有条件测试可能会非常冗长.... decltype似乎有点矫枉过正?

如何推断出类型?

谢谢

3 个答案:

答案 0 :(得分:1)

此代码无效。编译器无法根据返回类型推断模板参数,因此您应手动设置:

auto mat2 = mat1.transform<sub_material2>(state::composite2);

如果之前声明了mat2:

sub_material2 *mat2;
mat2 = mat1.transform<sub_material2>(state::composite2);

您正在尝试混合指针和非指针类型。

我建议你尝试以下方法:

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;
}
.
.
.
.
}

然后你可以这样:

sub_material1 mat1;
auto mat2 = mat1.transform(composite2{});

sub_material1 mat1;
sub_material2 mat2;

mat2 = mat1.transform(composite2{});

如果你愿意,你可以返回指针,但是mat2应该是sub_material2 *的类型。

答案 1 :(得分:0)

如果您想要的是以下内容:

sub_material3 ma3 ;
mat3 = mat1.transform(state::composite3)
然后答案是:你做不到。编译器必须在编译时知道要调用哪个版本的转换。你可以这样做:

template <enum class state>
struct state_material
{
    typedef type sub_material1 ;
} ;

然后专门化

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 ;
} ;

然后这样打电话:

mat2 = mat1.template transform<state_material<state::composite2>::type>()

答案 2 :(得分:0)

当前形式的代码根本不起作用,autodecltype都不会对此有所帮助。编译器无法推断出T的实际类型。因此,您必须在调用transform时指定该类型:

mat2 = mat1.transform<sub_material2>(state::composite2);

但是,仍然存在问题:transform返回T*,而不是T,即除非您声明mat2sub_material2*,否则分配将无效输入material

如果方法可以根据运行时参数返回不同类型的材料,则必须例如返回指向基类c(sapply(1:5, function(u) (1:5)[-u])) #[1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4 的对象的指针。模板用于制定编译时决策,但您的方法看起来像是运行时决定!