如何解决在 C++ 中使用可变参数函数编译错误
我有一段不能很好编译的代码。 我将可变参数函数和绑定函数一起使用。编译器错误信息显示
error: no match for call to ‘(std::_Bind<std::_Mem_fn<void (SimpleList::*)(int&&)>(std::_Place holder<1>,int)>) (SimpleList&)’ slistinitter(simpleList);
#include <iostream>
#include <functional>
template <typename T>
std::reference_wrapper<T> maybe_wrap(T& val)
{
std::cout << "this is lvalue\n";
return std::ref(val);
}
template<typename T>
T&& maybe_wrap(T&& val)
{
std::cout << "this is rvalue\n";
return std::forward<T>(val);
}
void print(){}
template<typename T,typename... Args>
void print(const T& t,Args&&... args)
{
std::cout << t << std::endl;
print(std::forward<Args>(args)...);
}
class SimpleList
{
public:
template<typename... Args>
void init(Args&&... args)
{
std::cout << __FUNCTION__ << std::endl;
print(std::forward<Args>(args)...);
}
};
template<typename SLIST>
class Collection
{
public:
template<typename SLIStiniTTER>
void initCollection(SLIStiniTTER slistinitter)
{
std::cout << __FUNCTION__ << std::endl;
SLIST simpleList;
slistinitter(simpleList);
}
template<typename... Args>
void init(Args&&... args)
{
initCollection(std::bind(&SLIST::template init<Args...>,std::placeholders::_1,maybe_wrap(std::forward<Args>(args))...));
}
};
class test
{
public:
void work(const std::string& p1)
{
std::cout << p1 << std::endl;
}
test(){}
test(const test&)
{
std::cout << "this is copy\n";
}
test(test&& t)
{
std::cout << "this is move\n";
}
friend std::ostream& operator<<(std::ostream& os,const test& t);
};
std::ostream& operator<<(std::ostream& os,const test& t)
{
os << "cool";
return os;
}
int main()
{
using Sample = Collection<SimpleList>;
Sample s;
test t;
int i = 2;
s.init(2);
return 0;
}
如果我使用 i 作为左值传递给 init 函数。它可以很好地编译。
解决方法
由 std::bind
生成的函子中的数据成员存储为 Lvalues。
成员对象 std::bind 的返回类型持有一个成员对象
输入从 std::forward(f) 构造的 std::decay::type,和一个
对象每个 args...,类型为 std::decay
您的代码可以简化为:
struct Foo {
template<class T>
void Bar(T&&) {}
};
int main() {
Foo f;
auto b = std::bind(&Foo::Bar<int>,std::placeholders::_1,2);
b(f);
}
代码无法编译。传递的 2
存储为左值,但我们指定有界函数的签名为 Foo::Bar(int&&)
-> 接受右值引用。左值不能绑定到右值。这就是问题所在。作为修复,我们可以在 int&
- Bar
的模板参数列表中传递 &Foo::Bar<int&>
。
您的代码更改为 std::bind(&SLIST::template init<Args&...>
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。