首先,如果我犯了很大的英语错误,我很抱歉,我是法国人,但我正尽力尽力写作!好吧,我正在努力使用C ++ 11可变参数模板。我想做一些有点棘手的事情。
确实,我想专门化我的模板的返回类型,知道它是一个可变参数模板。
我的目标是实现以下目标:
l.callFun<int>("addition", 40, 1, 1);
专门化对应于用户想要的返回类型。它是一个Lua绑定,所以如果用户不精确它,我无法确定返回类型(显然,默认情况下,如果没有特化,则返回void)。稍后,是Lua中调用的函数的名称。然后,3个整数对应于我的可变参数模板。
现在,我的模板看起来像这样:
template <typename Z, typename T, typename... U>
Z LuaScript::callFun(const std::string& name, const T& head, const U&... tail);
但似乎我无法对模板功能进行部分专业化。有没有人可以帮助我?
非常感谢!
答案 0 :(得分:1)
完美转发对辅助类成员函数的初始调用应该有助于你想要的东西。
template<typename Z>
struct callFun_helper {
template<typename T, typename... U>
static Z help(const std::string& name, const T& head, const U&... tail) {
Z thing;
//do something with "thing"
return thing;
}
};
template<typename Z, typename S, typename T, typename... U>
auto callFun(S&& s, T&& t, U&&... u)
-> decltype(callFun_helper<Z>::help(std::forward<S>(s), std::forward<T>(t), std::forward<U>(u)...)) {
return callFun_helper<Z>::help(std::forward<S>(s), std::forward<T>(t), std::forward<U>(u)...);
}
//main
callFun<string>("addition", 40, 1, 1)
如果您想了解更多关于您可以/不能使用它的信息,下面的链接可能会帮助您进行部分模板专业化。此外,如果您希望将来在StackOverflow继续获得答案,请不要忘记标记答案:)
答案 1 :(得分:1)
帮助和文档非常感谢pheedbaq,但最后,我找到了一个非常简单的解决方案。我没有这样做,所以我会试着用这种操作符重载方式来感谢你;)
我所做的是打包可变参数,并调用另一个模板来专门处理返回类型。所以我有类似的东西:
template <typename Z, typename... T>
Z LuaScript::callFun(const std::string& name, const T&... args)
{
Z ret;
callFunReal(args);
[...]
ret = returnType<Z>();
return (ret);
}
这真的很简单,但看不清楚该怎么做...感谢大家! :)
答案 2 :(得分:1)
不需要更改界面的解决方案是将函数调用转发到template<> class
,您可以专注于您的内容:
template<typename R, typename... Ts>
struct DoCallFun {
R operator()( LuaScript* self, std::string const& name, Ts&&... ts ) {
}
};
template <typename Z, typename... T>
Z LuaScript::callFun(const std::string& name, Ts&&... ts) {
return DoCallFun<Z, Ts...>()( this, name, head, std::forward<Ts>(ts)... )
}
我们在callFun
内实施DoCallFun
的正文。如果需要访问LuaScript
中的私有变量,我们会DoCallFun
为friend
。
现在,更好的解决方案可能是使用“traits class
”来处理大部分return
类型依赖行为。如果您需要根据return
类型调用其他函数,而不是为每个callFun
类型编写一次相同的return
,只会略有不同,您可以创建“traits {{ 1}}“您根据class
类型隔离差异。
如果类型为return
,则需要调用int CallAndReturnInt(...)
;如果类型为int
,则需要调用double CallAndReturnDouble(...)
。不要有两个double
的主体,而是写一个特征类:
callFun
以及基于template<typename T>
struct lua_return_traits;
template<>
struct lua_return_traits<int> {
template<typename... Ts>
static int call_and_return( Ts&&... ts ) {
return CallAndReturnInt( std::forward<Ts>(ts) );
}
};
template<>
struct lua_return_traits<double> {
template<typename... Ts>
static double call_and_return( Ts&&... ts ) {
return CallAndReturnDouble( std::forward<Ts>(ts) );
}
};
类型,您的方法应有所不同的其他方式的类似技巧。