编辑:我认为这个问题被错误地标记为重复,特别是对于给定的“重复”。请参阅下文。
今天我尝试(第一次)使用模板函数参数演绎。
我的目标是实现一个简单的状态系统。下面的代码(希望如此)显示了重要的部分(我没有测试它,它只是为了说明问题):
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'
当我明确指定模块时(如第三行所示),程序将编译。
我的问题:
编译器是否应该能够在前两行中推断出模块类型?!为什么它没有按预期工作?
有什么方法可以简单地调用SetStatus(OK);没有明确指定Module类型?用C ++ 11解决这个问题会更容易吗?
谢谢!
使用的编译器是g ++ 4.9.2
修改:我认为所谓的“重复”answer1和answer2中的“非受限上下文”不适用于此处。
其他情况中的经典非弱化上下文示例是:
template <typename T>
void g(typename Foo<T>::type);
我的情况不同:
template <typename T>
void SetStatus(enum T::Status localStatus)
其他情况中可能存在歧义,特别是因为Foo&lt; T&gt; ::类型的类型与T本身无关。 answer2明确指出了这一点。
我认为我的案例中没有任何歧义。如果我错了,请通过举例说明我的代码如何导致含糊不清来证明这一点。
正如我在评论中已经指出的那样,我认为通过逻辑(不是通过正确使用模板论证演绎语义,我显然做错了),编译器可以推断出类型。
请删除重复标记并回答我原来的问题。