如何在C++类的特殊版本和非特殊版本之间共享代码?

这是我要完成的工作的人为示例:

#include <iostream>
using namespace std;

template <size_t n> struct Y {
    int one() { return 1; }
    int two();
};

template <> struct Y<1> {
    int one() { return 11; }
    int two();
};

template <size_t n> int Y<n>::two() { return one() * 2; }

int main() {
    Y<1> X;
    cout << X.one();
    cout << X.two();
    return 0;
}

链接时此失败:
Undefined symbols for architecture x86_64:
  "Y<1ul>::two()", referenced from:
      _main in test-7c4ebe.o

但是,如果我将Y<1> X;更改为Y<2> X;,则编译成功就可以了。

我的目标是将two()的示例实现用于该类的专用和非专用版本。

我能够像这样解决继承问题:
#include <iostream>
using namespace std;

struct mixin {
    virtual int one() = 0;
    int two() { return one() * 2; }
};

template <size_t n> struct Y : public mixin {
    int one() { return 1; }
};

template <> struct Y<1> : public mixin {
    int one() { return 11; }
};

int main() {
    Y<1> X;
    cout << X.one();
    cout << X.two();
    return 0;
}

但是我认为这会在每次调用Y<n>.two()时导致不必要的v表查找,对吗?

有什么方法可以在专用版本和非专用版本之间共享代码,而又不会滥用继承和引起v表查找调用?

最佳答案

您根本不需要在one中添加mixin方法。只需使用带有非虚拟mixin方法的two即可与派生类Y共享其实现并使用CRTP。

#include <iostream>
using namespace std;

template <class Derive>
struct mixin {
    int two() { return ((Derive *)this)->one() * 2; }
};

template <size_t n> struct Y : public mixin <Y<n>> {
    int one() { return 1; }
};

template <> struct Y<1> : public mixin <Y<1>> {
    int one() { return 11; }
};

int main() {
    Y<1> X;
    cout << X.one();
    cout << X.two();
    return 0;
}

关于c++ - 在专用和非专用模板化结构之间共享代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36629722/

10-11 16:09