2

首先,如果我犯了很大的英语错误,我很抱歉,我是法国人,但我正在尽我所能写!好吧,我正在努力使用 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);

但似乎我无法对模板函数进行部分专业化。有没有人可以帮助我?

非常感谢!

4

3 回答 3

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 上继续获得答案,请不要忘记标记答案:)

为什么不专门化函数模板?

于 2013-05-31T19:58:58.413 回答
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);
}

这真的很简单,但看不出具体怎么做……谢谢大家!:)</p>

于 2013-06-01T04:16:59.393 回答
1

不需要更改界面的解决方案是将函数调用转发到 a 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我们实现了 inside的主体DoCallFun。如果它需要访问私有变量,LuaScript我们创建DoCallFun一个friend.

现在,更好的解决方案可能是class对大部分return依赖于 -type 的行为使用“特征”。如果您需要根据类型调用不同的函数,而不是为每个稍有差异的类型return编写一次相同的函数,您可以创建一个“特征”,在其中根据类型隔离差异。callFunreturnclassreturn

假设您需要调用int CallAndReturnInt(...)if type isintdouble CallAndReturnDouble(...)if type is 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) );
  }
};

以及其他方式的类似技术,您的方法应根据return类型而有所不同。

于 2013-06-01T09:47:02.713 回答