C ++:引用/指向成员变量的指针作为模板参数

时间:2016-11-03 12:34:39

标签: c++ templates reference member-variables

首先,我有这样的事情:

class Test {
    std::vector<int> a, b;
    void caller(...) { callee(...); }
    void callee(...) { /* Do stuff with 'a' */ }
}

我想要的是具有与callee完全相同但对于向量b的函数。要做到这一点,有两个明显的解决方案:

  • 传递矢量ab作为参数。但是,callee是一个递归函数,可以进行数百次调用,并将向量作为参数传递只是不必要的开销。
  • 复制函数callee并使用向量b,这将是最好的选择,尽管callee是一个很长的函数,我会有很多重复的代码

出于好奇,我去寻找模板部分,我发现可以用于

  

左值参考类型

     

指针类型

     

指向成员类型的指针

所以我试着这样做:

class Test {
    std::vector<int> a, b;
    void caller(...) { callee<a>(...); }
    template <std::vector<int> &x> void callee(...) { /* Do stuff with 'x' */ }
}

但我得到

  

错误:在常量表达式中使用'this'

有没有办法用引用或指针实现这个?

顺便说一句,我想要的东西可以看作是函数范围的#define

4 个答案:

答案 0 :(得分:7)

阵列甚至是元组,但是对成员的好老指点没有爱?

class Test {
    std::vector<int> a, b;

    void caller(/*...*/) { callee<&Test::a>(/*...*/); }

    template <std::vector<int> Test::*vec>
    void callee(/*...*/) { /* Do stuff with `(this->*vec)` */ }
};

答案 1 :(得分:4)

您不能将对数据成员的引用用作模板参数:模板是编译时的,并且在运行时之前不知道this的值。换句话说,对于Test类型的每个运行时对象,您需要单独的实例化(单独的二进制代码)。

可以做的是用数组替换ab,并通过索引将callee模板化到此数组中:

class Test {
    std::array<std::vector<int>, 2> ab;
    void caller(...) { callee<0>(...); }
    template <size_t idx>
    void callee(...) { /* Do stuff with 'ab[idx]' */ }
}

这样,您只获得callee的一个实例化(一个用于0,一个用于1),编译时索引完成(或至少可行)。 / p>

答案 2 :(得分:2)

只需使用立面:

class Test {
    std::vector<int> a, b;
    void caller_a(...) { callee(a); }
    void caller_b(...) { callee(b); }
    void callee(std::vector<int> &a_or_b, ...) {
    }
}

callee()将引用其参数,该参数将作为一个或另一个类成员传递。

答案 3 :(得分:1)

与@Angew的回答相同,你也可以使用std :: tuple,它非常有趣,因为你可以在你的被调用函数中使用不同类型的容器:< / p>

class Test {
    std::tuple<std::vector<int>, std::list<int> > ab;
    void caller(...) { callee<0>(...); }
    template <size_t idx>
    void callee(...) { 
    ...
    auto aIt = std::get<idx>(ab).begin(); // gets either the vector or the list depending on template value
    ...
    }
}