专门化可变模板的返回类型
Specializing return type for a variadic template
首先,如果我犯了很大的英语错误,我很抱歉,我是法国人,但我正在尽我所能写得最好!好吧,我正在努力与c++ 11可变模板。我想做点小技巧
实际上,我想对模板的返回类型进行专门化,因为我知道它是一个可变模板。
我的目标是实现如下:
l.callFun<int>("addition", 40, 1, 1);
专门化对应于用户想要的返回类型。这是一个Lua绑定,所以如果用户没有精确指定返回类型,我就无法确定返回类型(显然,如果没有特化,默认值将是void return)。是在Lua中调用的函数的名称。然后,这3个整数对应于我的可变模板。
现在,我的模板看起来像这样:
template <typename Z, typename T, typename... U>
Z LuaScript::callFun(const std::string& name, const T& head, const U&... tail);
但是我似乎不能对模板函数进行部分特化。有人能帮我吗?
非常感谢!
非常感谢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);
}
这真的很简单,但我不知道到底该怎么做…谢谢大家!:)
不需要更改接口的解决方案是将函数调用转发到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)... )
}
,我们在DoCallFun
中实现callFun
的主体。如果需要访问LuaScript
中的私有变量,我们将DoCallFun
改为friend
。
现在,一个更好的解决方案可能是对大部分return
类型依赖的行为使用"性状class
"。如果您需要基于return
类型调用不同的函数,而不是为每个略有不同的return
类型编写一次相同的callFun
,您可以创建一个"traits class
",其中您基于return
类型隔离差异。
如果类型为int
,则需要调用int CallAndReturnInt(...)
;如果类型为double
,则需要调用double CallAndReturnDouble(...)
。而不是有两个主体的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
类型而有所不同。
完美地转发对helper类成员函数的初始调用应该可以方便您实现所需的功能。
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上继续获得答案,不要忘记标记答案:)
为什么不特化函数模板?
- 如何获取std::result_of函数的返回类型
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 为什么返回类型中需要typename?C++
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 使用decltype尾部返回类型专门化函数模板
- 专门化可变模板的返回类型
- 如何使c++模板化函数与返回类型无关,以便将来专门化
- 用泛型返回类型专门化函数
- 在只有模板化返回类型的函数模板中混合模板专门化和enable_if
- 是否可以更改专门化模板函数的返回类型?