我有代码
void prints_one()
{ cout << "one" << endl; }
int main(int argc, char *argv[])
{
std::function<void()> foo;
foo = prints_one;
foo();
return 0;
}
按预期工作;它打印&#34;一个&#34;。我不知道的是在作业中调用哪个赋值运算符原型以及如何调用。看看cpp引用,看起来它可能就是这个函数
template <class Fn> function& operator= (Fn&& fn);
但如果那是被调用的原型,我就不会理解函数如何绑定到右值引用。谢谢!
更新:谢谢大家,我将阅读全民参考资料。关于40的两个答案;此代码打印出它是一个右值引用:
template<class Fn>
class Foo {
public:
Foo() {}
Foo& operator=(Fn&& x)
{
std::cout << std::boolalpha << std::is_rvalue_reference<decltype(x)>::value << std::endl;
}
};
void prints_one()
{
cout << "one" << endl;
}
int main(int argc, char *argv[])
{
Foo<void()> bar;
bar = prints_one;
}
这会打印true
答案 0 :(得分:8)
C ++标准意味着令人困惑!否则,像我一样的人只是因为他们在C ++标准得到发展的同时正在观看而不能玩智能。为此,我们决定应用于类型的&&
符号表示两个完全不同的符号,但也有混淆相关的内容:
T
,符号T&&
表示正在声明右值引用。auto&& x = ...
或函数模板template <typename T> void f(T&& x)
中,符号表示:确定类型和&#34;参考度&#34;这个论点。推导出的类型T
具有不同的类型,具体取决于作为参数传递的内容:
const
类型的非X
左值,则T
类型将推断为X&
,T&&
变为{{ 1}}作为参考,右值参考折叠成参考。X&
类型的const
左值,则X
类型将推断为T
,X const&
变为T&&
},由于相同的参考折叠。X const&
类型将被推断为T
,而X
将变为T&&
,因为没有任何内容可以崩溃。推动论证推论规则的动机是完美的转发:论证应该转发到下一层,理想情况下看起来就像在第一个地方推断出的论证一样。
考虑到这一点,被调用的X&&
的赋值运算符确实是
std::function<...>
其中函数的参数相应地推断出来。在你的具体例子中,实际传递的函数指针是通过衰减函数类型而动态创建的右值:函数不是真正的对象,不能在C ++中传递。正在形成除了调用指向函数的指针之外的访问它们。因此,参数是template <typename F>
std::function<...>::function(F&& f)
类型的右值。
答案 1 :(得分:2)
从here引用内容:
T&&
并非总是rvalue
参考。
&&
有时可能意味着rvalue
引用,但有时它意味着rvalue
引用或lvalue
引用。
我将尝试通过一个例子为上述做出贡献。请考虑以下代码:
#include <iostream>
#include <type_traits>
using namespace std;
template<class F>
void foo(F&& f)
{
std::cout << std::boolalpha << std::is_rvalue_reference<decltype(f)>::value << std::endl;
}
void prints_one()
{
cout << "one" << endl;
}
int main(int argc, char *argv[])
{
foo(prints_one);
foo([](){ cout << "lambda" << endl; });
return 0;
}
false
true
这意味着虽然foo
将T&&
作为输入参数,但由于prints_one
是lvalue
,因此输入参数{{1 }}将使用f
初始化,因此它将成为lvalue
引用。
另一方面,在lvalue
的第二次调用中,我们传递foo
,这实际上是lambda
引用。因此,输入参数rvalue
初始化为f
,因此它成为rvalue
引用。
因此,输入参数是推导为rvalue
引用还是lvalue
引用取决于在rvalue
调用时传递的输入参数。< / p>
关于更新的例子:
您正在使用赋值运算符foo
定义模板类Foo
。
在这种情况下,Foo<T>::operator=(T&&)
不是通用引用,因为没有类型扣除。
它更像是T&&
引用,因此您获得了rvalue
。
这是因为true
已被班级T
扣除。因此,对于成员重载运算符Foo<T>
的输入参数,不能进行类型推导。