繁体   English   中英

模板函数作为模板参数

[英]Template function as template argument

我正在学习模板并尝试实现此方法:

template <typename Func, typename Left, typename Right>
void flipArgs(Func* function, Left&& leftArg, Right&& rightArg) {
    function(std::forward<Right>(rightArg), std::forward<Left>(leftArg));
}

它需要一个函数和两个参数,并在翻转两个参数的情况下调用给定的函数。

它的功能很好,例如:

void test1(std::string, int) {
}

当我尝试这个功能时:

template <typename T>
void test2(T&& a, int) {
}

附:

string s("test");
flip(test2<string>, 42, s);

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

错误:无法将'std :: basic_string'左值绑定到'std :: basic_string &&'

我认为像T&&这样的函数参数是一个特殊情况,可以绑定到rvaluelvalue引用? 我究竟做错了什么?

我认为函数参数如T&&是一个特殊情况,可以绑定到[rvalues和lvalues]?

它是。 它基本上意味着模板可以为左值和右值具有不同的实例。

但是......当您在test2<string>明确地使Tstring时,您将选择一个特定的实例: void test2(string&&, int) string&&不再是那种特殊情况。 string&&只能绑定到字符串rvalues。 没有一个实例可以绑定rvalues和lvalues。

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

在这种情况下,您可以改为强制绑定到左值的实例化之一。 flip(test2<string&>, 42, s);这样的东西flip(test2<string&>, 42, s); ,它将实例化void test2(string&, int)

如果你真的想传递一个可以接受左值和右值的flip参数,你需要一个多态函数对象:

struct test2 {
    template <typename T>
    void operator()(T&& a, int) const {
    }
};
flip(test2{}, 42, s);

这里的关键是,在传递参数时,不会决定使用哪种特化,而是在稍后使用该参数时。

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

auto test2 = [](auto&& a, int) {};
flip(test2, 42, s);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM