时间:2016-08-22 16:58:28

标签: c++ templates metaprogramming partial specialization

我在学习c ++ 11/14时遇到的一些代码偶然发现了一个小问题。基本上我有一个Debugging类,我想处理所有的消息打印。大多数调试/日志记录类都有各种日志级别,但我想使用每个消息的标记。

为此,我有一个小枚举,我在其中定义我的标志及其值:

enum DebugFlag {
    Flag1 = 0,
    Flag2 = 1,
    Flag3 = 2
};

另外,我有一个Debugging类,我已经设法专门用于Flag类型,它运行得很好。

template<DebugFlag T>
class Debug {
public:
    template <typename U>
    static void print(U &&arg) {}
};

template <>
class Debug<static_cast<DebugFlag>(1)> {
public:
    static void print(std::string &&message) {
        std::cerr<<message<<"\n";
    }

    static void print(std::ostream &message) {
        std::cerr<<DebugStream()().str()<<"\n"; 
        DebugStream()().str(""); 
        DebugStream()().clear();  
    }

    static void print(std::string &message) {
        std::cerr<<message<<"\n";
    }
};

要调用此类,我使用如下调用:

Debug<Flag1>::print("Message\n"); // should not do anything with Flag1 compiled to 0 value
Debug<Flag2>::print("Message\n"); // should work

现在我想扩展此类以获取bool值,因此这样的调用将起作用:

Debug< Flag2<2 >::print("Message\n"); // should not do anything with Flag1 compiled to 2 value
Debug< Flag2<1 >::print("Message\n"); // should work

问题是我需要对我的Debug类进行第二次部分特化,即bool,而我无法准确确定语法是什么。 这是我最接近它的地方,但仍然无法弄清楚我做错了什么,或者如果没有上中学课程并且改变我想要的方式,它是否可行打电话给:http://cpp.sh/6yemn

1 个答案:

答案 0 :(得分:2)

我并不完全明白你希望如何使用你的课程,但这里有用的东西。

template <typename T, T v = T()>
class Debug {};

template <>
class Debug<Flag, Flag2> {
public:
    void f() { std::cout<<"This is good\n"; }
};

template <>
class Debug<bool, true> {
public:
    void f() { std::cout<<"This is good too\n"; }
};

问题是您需要指定类型:是否要使用boolFlag,然后使用值。您可以像这样实例化类:

Debug<bool, true> trueDebug;
Debug<Flag, Flag2> flag2Debug;

除非您添加专业化,否则其他实例将不具有f功能。例如:

template <Flag v>
class Debug<Flag, v> {
public:
    void f() { std::cout<<"This is bad\n"; }
};

Live example