首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板函数作为模板参数

模板函数作为模板参数
EN

Stack Overflow用户
提问于 2013-10-22 11:37:46
回答 1查看 179关注 0票数 4

我正在学习模板,并尝试实现这个方法:

代码语言:javascript
复制
template <typename Func, typename Left, typename Right>
void flipArgs(Func* function, Left&& leftArg, Right&& rightArg) {
    function(std::forward<Right>(rightArg), std::forward<Left>(leftArg));
}

它接受一个函数和两个参数,调用给定的函数并翻转两个参数。

它的功能很好,例如:

代码语言:javascript
复制
void test1(std::string, int) {
}

当我尝试这个函数时:

代码语言:javascript
复制
template <typename T>
void test2(T&& a, int) {
}

通过以下方式:

代码语言:javascript
复制
string s("test");
flip(test2<string>, 42, s);

编译器(g++ 4.7.1)告诉我:

错误:无法将“std::basic_string”值绑定到“std::basic_string&&”

我认为像T&&这样的函数参数是可以绑定到rvaluelvalue引用的特例吗?我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-22 11:41:09

我认为像T&&这样的函数参数是可以绑定到rvalue和lvalue的特例吗?

它是。它基本上意味着,对于lvalue和rvalue,模板可以有不同的实例化。

然而..。当您显式地使Ttest2<string>中成为string时,您将选择一个特定的实例化:void test2(string&&, int)string&&不再是那种特例了。string&&只能绑定到字符串rvalue。没有一个实例化可以同时绑定到rvalue和lvalue。

通常,我建议不要显式地传递函数模板参数(除非这些参数是有意的,比如std::forwardstd::make_unique)。

在这种情况下,您可以强制其中一个绑定到lvalue的实例化。类似于flip(test2<string&>, 42, s);,它将实例化void test2(string&, int)

如果您真的想将一个参数传递给可以同时接受lvalue和rvalue的flip,则需要一个多态函数对象:

代码语言:javascript
复制
struct test2 {
    template <typename T>
    void operator()(T&& a, int) const {
    }
};
flip(test2{}, 42, s);

这里的关键是,在传递参数时,不会决定使用哪一种专门化,而只是在稍后使用该参数时才作出决定。

为了完整起见,在C++14中实际上可以使用新的lambda语法创建匿名多态函数对象:

代码语言:javascript
复制
auto test2 = [](auto&& a, int) {};
flip(test2, 42, s);
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19516781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档