如何在可变模板参数中绑定不可移动对象的引用?
How to bind reference of non-movable object in variadic template arguments?
在下面的最小示例中:
#include <iostream>
#include <functional>
class Non_movable{
public:
Non_movable(void){ }
Non_movable(const Non_movable& other) = delete;/* Copy constructor */
Non_movable(Non_movable&& other) = delete; /* Move constructor */
Non_movable& operator=(const Non_movable& other) = delete; /* Copy assignment */
Non_movable& operator=(Non_movable&& other) = delete; /* Move assignment */
};
template<typename ...T>
std::function<void(int)> make_bound(T... args, std::function<void(T..., int)> fun){
return std::bind(fun, args..., std::placeholders::_1);
}
int main(int argc, char** agrs){
Non_movable no_move;
make_bound<Non_movable&>(no_move, [](Non_movable&, int num){
std::cout << num << std::endl;
})(6);
return 0;
}
在 --std=c++14 上编译时出现一大堆编译错误,这是可以理解的,因为可变参数模板中的每个参数都应该使用 std::ref
关键字来实现可编译。
有趣的是,如果五人一组成为默认值,而不是删除,编译通过,函数调用的行为就好像模板是用左值 Non_movable
调用的,这是为什么?
有没有办法让它可以使用可变参数模板进行编译?
在参数包扩展中,您可以编写至少包含一个参数包的任何模式,请参阅https://en.cppreference.com/w/cpp/language/parameter_pack。
这意味着在你的 make_bound 函数中你可以只写
return std::bind(fun, std::ref(args)..., std::placeholders::_1);
请在此处找到适合您的最小示例:https://onlinegdb.com/XhTBHpW9X
除此之外,您的 no_move 对象是一个左值,因此它作为左值传递给 make_bound,无论 copy/move 构造函数和赋值运算符是否被默认或删除。
在下面的最小示例中:
#include <iostream>
#include <functional>
class Non_movable{
public:
Non_movable(void){ }
Non_movable(const Non_movable& other) = delete;/* Copy constructor */
Non_movable(Non_movable&& other) = delete; /* Move constructor */
Non_movable& operator=(const Non_movable& other) = delete; /* Copy assignment */
Non_movable& operator=(Non_movable&& other) = delete; /* Move assignment */
};
template<typename ...T>
std::function<void(int)> make_bound(T... args, std::function<void(T..., int)> fun){
return std::bind(fun, args..., std::placeholders::_1);
}
int main(int argc, char** agrs){
Non_movable no_move;
make_bound<Non_movable&>(no_move, [](Non_movable&, int num){
std::cout << num << std::endl;
})(6);
return 0;
}
在 --std=c++14 上编译时出现一大堆编译错误,这是可以理解的,因为可变参数模板中的每个参数都应该使用 std::ref
关键字来实现可编译。
有趣的是,如果五人一组成为默认值,而不是删除,编译通过,函数调用的行为就好像模板是用左值 Non_movable
调用的,这是为什么?
有没有办法让它可以使用可变参数模板进行编译?
在参数包扩展中,您可以编写至少包含一个参数包的任何模式,请参阅https://en.cppreference.com/w/cpp/language/parameter_pack。 这意味着在你的 make_bound 函数中你可以只写
return std::bind(fun, std::ref(args)..., std::placeholders::_1);
请在此处找到适合您的最小示例:https://onlinegdb.com/XhTBHpW9X
除此之外,您的 no_move 对象是一个左值,因此它作为左值传递给 make_bound,无论 copy/move 构造函数和赋值运算符是否被默认或删除。