为什么这段代码可以编译?(使用 g++ 和 clang++ 测试)
以下代码用于接受函数并从中创建转发 std::function 的工厂方法。如您所见,内部的 lambda 接受 const Arg&
参数并将它们转发给给定的函数。
在 main()
中,我使用 factory()
创建一个到 test_func()
的转发器,它接受一个非常量引用参数.我不明白的是为什么这不会产生关于从参数中丢弃 const 限定符的错误。
请注意,确实在 main()
中创建的类 C
的实例在传递时没有创建任何拷贝。
#include <functional>
#include <iostream>
class C
{
public:
C() {}
C(const C&)
{
std::cout << "C copy\n";
}
};
int test_func(C& cref)
{
return 0;
}
template<typename Ret, typename... Arg>
std::function<Ret (const Arg&...)> factory(Ret (*func) (Arg...))
{
return [ func ] (const Arg&... arg) -> Ret {
return (func)(arg...);
};
}
int main() {
auto caller = factory(test_func);
C c;
caller(c);
return 0;
}
最佳答案
如评论中所述,您应该使用完美转发(请参阅 Scott Meyers 在 Universal reference 上的介绍)。
在你的情况下,它应该是:
#include <functional>
#include <iostream>
#include <utility>
class C
{
public:
C() {}
C(const C&)
{
std::cout << "C copy\n";
}
};
int test_func(const C& )
{
return 0;
}
template<typename Ret, typename... Arg>
std::function<Ret (Arg...)> factory(Ret (*func) (Arg...))
{
return [ func ] (Arg&&... arg) -> Ret {
return func(std::forward<Arg>(arg)...);
};
}
int main() {
auto caller = factory(test_func);
const C c;
caller(c);
}
请注意,我在您的 main()
中将 C c;
更改为 const C c;
,并且我修改了 test_func。
如果你想避免创建拷贝,你必须确保 test_func 函数没有按值获取。它应该通过引用(const of non-const)。
关于C++ 模板允许丢弃 const 引用限定符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19654835/