在C ++中实现基于模板的可选类成员的最有效方法是什么?

时间:2017-06-01 14:07:43

标签: c++ performance templates

我有一个性能关键型应用程序,需要通过各种traits类修改我的类的行为。一些更复杂的变体需要主类中的其他类成员。

所以我的问题是:根据使用的特征类,提供此类成员的最有效方法是什么?

我想拥有的是这样的:

template <class Traits> MainClass {

    typedef typename Traits::MemberType MT;

public:
    MT my_member;

    void do_something() {
        std::cout << Traits::get_number(this) << std::endl;
    }

    ...

};

class Zero {
public:
    typedef void MemberType;

    static inline int get_number(MainClass<Zero>*) { return 0; }
}

class IntegerNumber {
public:
    typedef int MemberType;

    static inline int get_number(MainClass<IntegerNumber>* myclass) { return myclass->my_member; }
}

现在这不起作用,因为你不能声明一个变量void。但由于我将拥有大量的MainClass实例,并且有许多不同的traits类,我不希望每个可能的特性都有“虚拟”变量。

实现这一点的一种可能性是通过继承,但这正是我想通过首先使用模板来避免的,因为这可能导致性能损失,尤其是在具有多个不同特征时。

所以我的问题是:

  1. 我可以告诉编译器消除类中某些未使用的成员变量吗?
  2. 你会如何处理这个问题?还有其他可能性来实现吗?
  3. 哪种方法效率最高?

1 个答案:

答案 0 :(得分:2)

对于这个例子,这应该做,但我不知道这对你的需求是否足够。

#include <algorithm>
#include <iostream>
#include <vector>

template <class MemberType>
class MainClassBase
{
public:
    MemberType my_member;
};

template <>
class MainClassBase<void>
{
};

template <class Traits> 
class MainClass : public MainClassBase<typename Traits::MemberType> {

public:

    void do_something() {
        std::cout << Traits::get_number(this) << std::endl;
    }

};

class Zero {
public:
    typedef void MemberType;

    static inline int get_number(MainClass<Zero>*) { return 0; }
};

class IntegerNumber {
public:
    typedef int MemberType;

    static inline int get_number(MainClass<IntegerNumber>* myclass) { return myclass->my_member; }
};
class String {
public:
    typedef std::string MemberType;

    static inline std::string get_number(MainClass<String>* myclass) { return myclass->my_member; }
};

int main()
{
    MainClass<Zero> mainClassZero{};

    MainClass<IntegerNumber> mainClassInteger{};
    mainClassInteger.my_member = -1;

    MainClass<String> mainClassString{};
    mainClassString.my_member = "asd";

    mainClassZero.do_something();
    mainClassInteger.do_something();
    mainClassString.do_something();
}

演示:http://coliru.stacked-crooked.com/a/013aabb763149596

如果您的类型是标准布局,则必须优化空基类(在C ++ 11和更高版本中)。如果不是,那么它仍然很可能会被优化。