首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将std::tr1::绑定与std::vector::push_back结合使用

将std::tr1::绑定与std::vector::push_back结合使用
EN

Stack Overflow用户
提问于 2011-05-15 17:25:46
回答 4查看 2.2K关注 0票数 2

为什么我的VS2010无法编译这段代码:

代码语言:javascript
运行
复制
#include <functional>
#include <vector>
int main()
{
    std::vector<int> vec;
    std::bind(&std::vector<int>::push_back, std::ref(vec), 1)();
    return 0;
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-15 18:37:45

试试这个:

代码语言:javascript
运行
复制
struct push_back {
    void
    operator()(std::vector<int>& vector, int i) const
    {
        vector.push_back(i);
    }
};

// somewhere else:
std::vector<int> vec;
std::tr1::bind(push_back(), std::tr1::ref(vec), 1)();

请注意,使用C++03时,push_back不能是本地类型;使用C++11时,它可以是本地类型,但使用lambda会更惯用(并且完全等效)。

很可能,您的实现为std::vector<T>::push_back提供了重载,因此必须消除其地址的歧义。如果发生这种情况,您的编译器应该已经为您提供了适当的错误消息。在任何情况下,你都应该解释你所说的“这不可能”是什么意思。

重点是不使用这样的帮助器函数。-品红色

那你为什么不把它放在问题里?我无法读懂你的心思。

您还可以尝试执行以下操作:

代码语言:javascript
运行
复制
std::vector<int> vec;
void (std::vector<int>::*push_back)(int const&) = &std::vector<int>::push_back;
std::tr1::bind(push_back(), std::tr1::ref(vec), 1)();

我相信这并不能保证成功。

票数 3
EN

Stack Overflow用户

发布于 2011-05-15 18:31:10

你应该更具体地解释为什么这似乎对你不起作用。

代码语言:javascript
运行
复制
#include <iostream>
#include <tr1/functional>
#include <vector>

int main(int argc, char* argv[]) {
    std::vector<int> vec;
    std::tr1::bind(&std::vector<int>::push_back, std::tr1::ref(vec), 1)();
    std::cout << "vec.size = " << vec.size() << std::endl;
    std::cout << "vec[0] = " << vec[0] << std::endl;
    return 0;
}

$ gcc -o test -lstdc++ test.cpp && ./test
vec.size = 1
vec[0] = 1

更新: Luc Danton是对的,这里的问题是push_back过载。请参阅问题Are there boost::bind issues with VS2010 ?。此外,请注意,该问题不仅限于push_back,请参阅Visual Studio 2010 and boost::bind

票数 5
EN

Stack Overflow用户

发布于 2011-05-15 21:24:58

底线是你想要做的事情在可移植的C++中是不可能的。保证在C++11编译器中重载std::vector<>::push_back,因为至少必须有一个用于左值的重载和一个用于右值的重载。

通常,当获取重载成员函数的地址时,C++11 FDIS中的§13.4/1告诉我们,我们可以控制我们要获取的地址是哪个重载:

不带参数的重载函数名的使用在某些上下文中被解析为重载集中特定函数的函数、指向函数的指针或指向成员函数的指针。函数模板名称被认为是在这样的上下文中命名一组重载函数。所选函数的类型与context中要求的目标类型的函数类型相同。注意:即在匹配指向成员的指针函数类型时,忽略该函数所属的类。-end注意到目标可以是

  • 正在初始化的对象或引用,
  • 赋值的左侧,
  • 函数的参数,
  • 用户定义运算符的参数,
  • 函数、运算符函数或转换的返回值,显式类型转换,或
  • 非类型代码

重载的函数名前面可以有&运算符。重载函数名不能在未列出参数的上下文中使用。注意:重载函数名周围的任何多余的括号都将被忽略。-end笔记

问题来自§17.6.5.5/2:

通过将带有默认值的参数添加到成员函数签名,实现可以在类中声明其他非虚拟成员函数签名;因此,C++标准库中的类的成员函数的地址具有未指定的类型。

因此,获取标准库类成员函数的地址是不可移植的,因为这样的表达式的类型根据定义是不可知的,除非在逐个实现的基础上。

Luc Danton提出的解决方法(特别是使用lambda)也是我推荐的:

代码语言:javascript
运行
复制
std::vector<int> vec;
[&](){ vec.push_back(1); }();
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6007563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档