8

首先,我有这样的事情:

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

callee 我想要的是有一个与vector完全相同的功能b。为此,有两个明显的解决方案:

  • 传递向量ab作为参数。但是,callee它是一个递归函数,可以进行数百次调用,并且将向量作为参数传递只是不必要的开销。
  • 复制函数callee并使用 vector 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

4 回答 4

9

数组甚至元组,但不喜欢旧的指向成员的指针?

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)` */ }
};
于 2016-11-03T13:41:25.750 回答
4

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

可以做的是用一个数组替换a和,并通过索引模板化到这个数组中:bcallee

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(一个 for0和一个 for 1),并在编译时完成(或至少可行)索引。

于 2016-11-03T13:08:53.533 回答
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()将引用其参数,该参数将作为一个或另一个类成员传入。

于 2016-11-03T12:39:07.923 回答
1

在与@Angew 的回答相同的逻辑中,您也可以使用std::tuple,这很有趣,因为使用元组您还可以在被调用函数中使用不同类型的容器:

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
    ...
    }
}
于 2016-11-03T13:25:35.237 回答