具有枚举类型的类的模板参数推导?

时间:2016-07-07 12:36:25

标签: c++ templates enums argument-deduction

编辑:我认为这个问题被错误地标记为重复,特别是对于给定的“重复”。请参阅下文。

今天我尝试(第一次)使用模板函数参数演绎。

我的目标是实现一个简单的状态系统。下面的代码(希望如此)显示了重要的部分(我没有测试它,它只是为了说明问题):

class StatusBase
{
    int m_globalStatus;

protected:
    // The module type should be found by template argument deduction
    template <class Module>
    void SetStatus(enum Module::Status localStatus)
    {
        // Do something with Module
        m_globalStatus = SomeOtherModule<Module>::ToGlobal(localStatus);
    }
};

以下是一些类可以使用StatusBase类的方法。

class DerivedA : public StatusBase
{
public:
    enum Status {
        OK,
        WARNING,
        ERROR
    };
    DerivedA ()
    {
        SetStatus(OK);           // doesn't work
        SetStatus(DerivedA::OK); // doesn't work
        SetStatus<DerivedA>(OK); // this works
    }
};

另一个类会有不同的枚举:

class DerivedB : public StatusBase
{
public:
    enum Status {
        OTHER_OK,
        OTHER_WARNING
    };
    ...
};

有趣的部分是对SetStatus的调用。对于前两行不起作用,编译器会抱怨它

couldn't deduce template parameter `Module'

当我明确指定模块时(如第三行所示),程序将编译。

我的问题:

  1. 编译器是否应该能够在前两行中推断出模块类型?!为什么它没有按预期工作?

  2. 有什么方法可以简单地调用SetStatus(OK);没有明确指定Module类型?用C ++ 11解决这个问题会更容易吗?

  3. 谢谢!

    使用的编译器是g ++ 4.9.2

    修改:我认为所谓的“重复”answer1answer2中的“非受限上下文”不适用于此处。

    其他情况中的经典非弱化上下文示例是:

    template <typename T>
    void g(typename Foo<T>::type);
    

    我的情况不同:

    template <typename T>
    void SetStatus(enum T::Status localStatus)
    
    1. 其他情况中可能存在歧义,特别是因为Foo&lt; T&gt; ::类型的类型与T本身无关。 answer2明确指出了这一点。

    2. 我认为我的案例中没有任何歧义。如果我错了,请通过举例说明我的代码如何导致含糊不清来证明这一点。

    3. 正如我在评论中已经指出的那样,我认为通过逻辑(不是通过正确使用模板论证演绎语义,我显然做错了),编译器可以推断出类型。

    4. 请删除重复标记并回答我原来的问题。

0 个答案:

没有答案