基于派生类型的编译时行为分支

时间:2018-08-30 10:18:43

标签: c++ polymorphism c++17 template-meta-programming

我有一对类FS和DS,它们都从另一个类S派生。我有一个函数,我将S *(即FS或DS)传递给该函数,该函数进一步调用传递相同S的另一个函数。 *。在此最终功能中,我需要基于S是FS还是DS来具有不同的行为,但由于它位于关键路径上,因此希望在编译时解析此分支。我该如何实现?我感觉到涉及元编程和或constexpr的事情-我不想为每个通行证进行虚拟呼叫

为简洁起见,省略了其他细节

class S {};
class FS : public S {};
class DS : public S {};

void func_2(Space *s) {
     // common code
     // branch based on lowest type of s
     // common code
}

void func_1(Space *s) {
    // common code
    func_2(s);
}

2 个答案:

答案 0 :(得分:5)

func_1func_2都应该被模板化,可能使用一些SFINAE来确保调用类型是从S派生的。然后您只需执行if constexpr(std::is_same<std::decay_t<T>, FS>::value)并为不同的类实现不同的行为。
如果将基类指针传递给该方法,那么我相信在编译时将无法检索派生类型。

答案 1 :(得分:4)

您不能在编译时执行此操作,因为赋予函数的实际参数及其评估只能在运行时进行。

相反,您可以做的是将类型之间的关系移至编译时,也许您可​​以阅读《好奇地重复的模板模式》。

template <typename ActualType>
struct S  {};

struct DS:S<DS> {};

template <typename ActualType>
void func(S<ActualType>const& s)
{
    if constexpr(std::is_same<ActualType, DS>::value)
    //...
    else
    //...
}