使用单例进行元编程

时间:2014-01-15 21:29:16

标签: c++ boost c++11

我想在两个不同的代码路径之间进行选择,具体取决于单例类的枚举值。 Singleton类继承自“CSingleton”类型,其中T是新类的类型。

enum class Paths
{
    PATH_ONE = 0,
    PATH_TWO,    
}

template<Paths pathValue>
class Foo : public CSingleton<Foo>
{
public:
    Foo()
    {
        if(pathValue == Paths::PATH_ONE)
             myValue = 11;
        else if(pathValue == Paths::PATH_TWO)
             myValue = 22;
    }

    int myValue;

};

然后在使用对象时,我可以这样做:

assert(11 == Foo<Paths::PATH_ONE>::Instance().myValue);

要明确,Instance()就是创建对象的东西。

我正在尝试做的是否有名字?是否有Boost或C ++ 11的一部分可以帮助我?

谢谢!

3 个答案:

答案 0 :(得分:0)

您正在尝试做出运行时决策并在编译时进行。对于这个简单的示例,您只需将枚举值强制转换为int

即可
myValue = static_cast<int>(pathValue);

但更好的方法可能是创建一个带参数的构造函数:

Foo(const Paths& path)
{
    if(path == Paths::PATH_ONE)
    {
         // do something
    }
    else if(path == Paths::PATH_TWO)
    {
         // do something else
    }
}

在这种情况下,您的班级不再需要成为模板:

class Foo : public SomeParent { ... };

另一个解决方案是专门为值设置模板,但是你需要2个类声明。

答案 1 :(得分:0)

解决此类问题的一种常用的元编程方法(独立于单独一个或多个类别!)如下:

enum Selections
{
    PATH_ONE ,
    PATH_TWO ,
};

class ImplBase : public ImplBase
{
    // Declare an interface and common implementation bits
}

class ImplBaseOne : public ImplBase
{
    // Implement details for PATH_ONE
};

class ImplBaseTwo
{
    // Implement details for PATH_TWO
};

template<Selections Choice>
struct Selector
{
     typedef void Result; // This should result in a compiler error for 
                          // invalid/unknown specializations
};

template<>
struct Selector<PATH_ONE>
{
     typedef ImplBaseOne Result;
};

template<>
struct Selector<PATH_ONE>
{
     typedef ImplBaseOne Result;
};

template<>
struct Selector<PATH_TWO>
{
     typedef ImplBaseTwo Result;
};

template<Selections Choice>
class ExposedClass : public Selector<Choice>::Result
{
    // ...
}

答案 2 :(得分:0)

您可以通过多种方式在编译时执行所需的操作,转换为模板专业化:

1。仅为值

template<Paths> struct MyValue;

template<> struct MyValue<Paths::PATH_ONE> { static constexpr int value = 11; };
template<> struct MyValue<Paths::PATH_TWO> { static constexpr int value = 22; };

所以你有:

Foo() { myValue = MyValue<pathValue>::value; }

2。对于函数

您可以创建多个函数/方法参数化

template<Paths> void MyAssignVariable(int& var);

template<> void MyAssignVariable<Paths::PATH_ONE>(int& var) { var = 11; };
template<> void MyAssignVariable<Paths::PATH_TWO>(int& var) { var = 22; };

所以你有:

Foo() { MyAssignVariable<pathValue>(myValue); }

由于无法在功能上进行部分专业化,因此首选:

template<Paths> struct PathSpecialization;

template<> struct PathSpecialization<Paths::PATH_ONE> {
    static void MyAssignVariable(int& variable) { variable = 11; };
    // You may add other methods here.
};
template<> struct PathSpecialization<Paths::PATH_TWO> {
    static void MyAssignVariable(int& variable) { variable = 22; };
    // You may add other methods here.
};

所以你有:

Foo() { PathSpecialization<pathValue>::MyAssignVariable(myValue); }