C++ 返回类型的问题
我有一门课:C++ 返回类型的问题,c++,metaprogramming,C++,Metaprogramming,我有一门课: struct Policy_1 { void signalFailure() { throw std::exception(); } }; struct Policy_2 { void* signalFailure() { return nullptr; } }; template
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);
}
}
};
结构策略1
{
无效信号失效()
{
抛出std::exception();
}
};
结构策略2
{
void*signalFailure()
{
返回空ptr;
}
};
模板
结构我的
{
模板
T*fnc(整数值)
{
如果(!值)
{
返回策略::signalFailure();//问题出在这里
}
其他的
{
返回新的int(值);
}
}
};
问题在于,依赖于策略类signalFailure会抛出或返回null ptr,但我从编译器那里得到了错误(即使策略设置为它确实抛出),它无法将void转换为(T*)——这取决于我用什么替换了tea;现在,我确实理解了问题所在——编译器进行语法检查,并发现根据此策略,signalFailure返回void,因此即使在实际中抛出signalFailure,它也无法解析它
我有两个选择:a) 将void*声明为signalFailure的结果类型
b) 在fnc中将void声明为结果类型,并将结果类型移动到此fnc的args列表中 或
c) 在fnc中执行一些宏或元编程(这里是真正的Q),这将在编译时确定(返回Policy::etc或Policy::etc),我认为这是最好的选择。当然,如果你们中有人有更好、更优雅的想法,我们非常欢迎展示它。如果投掷策略确实有返回值(尽管未使用),我不会感到震惊,这可能是我会做的。但是,如果您不想避免
void*
,那么您还可以制作signalFailure
方法模板,并从fnc调用Policy::signalFailure()
(从而允许signalFailure
方法返回更强类型的t*
)
另一方面,
signalFailure
方法应该是静态的,或者My
应该从您的Policy类中私下继承。如果抛出的策略确实有返回值(尽管未使用),我不会感到震惊,这可能是我会做的。但是,如果您不想避免void*
,那么您还可以制作signalFailure
方法模板,并从fnc调用Policy::signalFailure()
(从而允许signalFailure
方法返回更强类型的t*
)
另一方面,
signalFailure
方法应该是静态的,或者My
应该从您的策略类私下继承。我看到您使用的是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.
}
}
};
模板
结构我的
{
模板结构函数辅助对象{
静态T func(){return Policy::signalFailure();}
};
模板结构函数辅助对象{
静态void*func(){Policy::signalFailure();返回nullptr;}
};
模板
T*fnc(整数值)
{
如果(!值)
{
返回func_helper::func();
}
其他的
{
返回新的int(value);//如果int*无法转换,则编译错误
//与策略的类型关联。
}
}
};
编辑:请稍候。这个代码是严重错误的。您正在返回一个新的int(),作为T*?这段代码不需要修复,它需要整个模块的剥离。我看到您使用的是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.
}
}
};
模板
结构我的
{
模板结构函数辅助对象{
静态T func(){return Policy::signalFailure();}
};
模板结构函数辅助对象{
静态void*func(){Policy::signalFailure();返回nullptr;}
};
模板
T*fnc(整数值)
{
如果(!值)
{
返回func_helper::func();
}
其他的
{
返回新的int(value);//如果int*无法转换,则编译错误
//与策略的类型关联。
}
}
};
编辑:请稍候。这个代码是严重错误的。您正在返回一个新的int(),作为T*?此代码不需要修复,它需要整个模块剥离。不应该是静态的吗?@sharptooth我同意,尽管我希望在实际代码中他从策略中生成异常消息\u 1不应该是静态的
signalFailure()
是静态的吗?@sharptooth我同意,虽然我希望在实际代码中,他会从策略中生成一条异常消息。\u 1nullptr是C++之前C++CLI的一部分,但如果signalFailure返回void,则第二次返回将无效。多亏了这一点(我必须承认这非常优雅),但是否可以使用宏执行此操作?然后我只需要编写,即CHECK_POLICY(POLICY),然后这将扩展到代码的正确版本?无论如何,我接受你的答案,但如果你能想出一些宏或它会很好。我觉得也很优雅。谢谢。@There:这是模板元编程。你不必对它做任何事,只要打电话就行了。您不需要每次都编写CHECK_策略,只需编写一次。nullptr在C++0x1之前是C++CLI的一部分,但是如果signalFailure返回void,则第二次返回将无效。多亏了它的工作原理(我必须承认它非常优雅),但是否可以使用宏执行此操作?然后我只需要编写,即CHECK_POLICY(POLICY),然后这将扩展到代码的正确版本?无论如何,我接受你的答案,但如果你能想出一些宏或它会很好。我觉得也很优雅。谢谢。@There:这是模板元编程。你不必对它做任何事,只要打电话给我就行了