我有一个课程:
struct Policy_1
{
void signalFailure()
{
throw std::exception();
}
};
struct Policy_2
{
void* signalFailure()
{
return nullptr;
}
};
template<class Policy>
struct My
{
template<class T>
T* fnc(int value)
{
if (!value)
{
return Policy::signalFailure();//Here is the problem
}
else
{
return new int(value);
}
}
};
问题在于取决于Policy类signalFailure抛出或返回nullptr但是我从编译器得到错误(即使设置了它确实抛出了Policy)它无法将void转换为(T *) - 取决于我替代茶;现在,我确实理解问题所在 - 编译器进行语法检查并发现从此策略中,signalFailure返回void,因此即使在实践中signalFailure抛出也无法解析它。
我认为有两种选择:
a)声明void *作为signalFailure的结果类型
b)在fnc中声明void作为结果类型,并将结果类型移动到此fnc的args列表中
或
c)在我的fnc中做一些(这里是你真正的Q)宏或元编程,它将在编译时确定(返回Policy :: etc或者只是Policy :: etc)并且我认为这是最好的选择。当然,如果你们中的某个人有更好,更优雅的想法,那么非常欢迎你们展示它。
答案 0 :(得分:1)
我看到你正在使用nullptr-这意味着你必须使用C ++ 0x。在这种情况下,使用decltype来解决这个问题是微不足道的。
template<class Policy>
struct My
{
template<typename T> struct func_helper {
static T func() { return Policy::signalFailure(); }
};
template<> struct func_helper<void> {
static void* func() { Policy::signalFailure(); return nullptr; }
};
template<class T>
T* fnc(int value)
{
if (!value)
{
return func_helper<decltype(Policy::signalFailure())>::func();
}
else
{
return new int(value); // Compile error if int* cannot be converted
// to the type of the policy.
}
}
};
编辑:暂停一下。这段代码严重错误。你正在返回一个新的int(),如T *?这段代码不需要修复,需要整个模块翻录。
答案 1 :(得分:0)
如果投掷政策确实有一个返回值,虽然未使用,我不会感到震惊,这可能就是我要做的。但是,如果你不想避免void *
,你也可以制作signalFailure
方法模板并从fnc调用Policy::signalFailure<T>()
(从而允许signalFailure
方法返回更强类型T *
)。
另外,signalFailure
方法应该是静态的,或者My
应该私有地从Policy类继承。