【问题标题】:std::vector Semantic issue while using push_back使用 push_back 时的 std::vector 语义问题
【发布时间】:2014-03-12 11:16:44
【问题描述】:
#include <vector>
typedef void (* const MyType)(void *, void *);
static void exampleFunction(void *param1, void *param2)
{
    // ...
}

int main(int argc, char* argv[])
{
    std::vector<MyType> myVector;
    myVector.push_back(exampleFunction); // fails.
} 

这是代码,//fails 的行似乎不可编译。 我把它注释掉,没有问题。但如果它打开,这就是我在 XCode 中遇到的错误:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/memory:1593:27: Cannot initialize a parameter of type 'void *' with an lvalue of type 'void (*const *)(void *, void *)'

有人知道为什么会这样吗?

提前致谢。

【问题讨论】:

  • 因为它是const。毕竟 STL 对元素有一些要求。
  • std::vectorconst 通常不能一起玩。
  • 一个离题建议:尽量避免void*。改用模板。

标签: c++ vector stl constants std


【解决方案1】:

Vector(以及任何其他标准容器)以特定方式管理其元素的内存。它允许执行的许多操作要求元素不能是const。例如,它的fill_n 方法用相同值的副本填充范围。或者使用placement构造元素new

 /**
 * Constructs an object in existing memory by invoking an allocated
 * object's constructor with an initializer.
 */
 template<typename _T1, typename _T2>
  inline void
  _Construct(_T1* __p, const _T2& __value)
  {
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 402. wrong new expression in [some_]allocator::construct
    ::new(static_cast<void*>(__p)) _T1(__value);
                     ^
                    // here you would get an error: invalid static_cast
  }

没有像std::vector 这样带有const 元素的东西。


解决方案:

使指针非const:

typedef void (* MyType)(void *, void *);

【讨论】:

  • 谢谢 :) 这就像一个魅力,我不知道向量有这样的限制。我会记住这一点,谢谢大家。
【解决方案2】:

为了在许多不同的编译器中实现最大的兼容性,请进行以下更改:

typedef void (*MyType)(void *, void *);

^删除常量

void exampleFunction(void *param1, void *param2)

^删除静态

myVector.push_back(&exampleFunction);

^添加和号

【讨论】:

  • 感谢您的提示,第一个提示解决了我的问题,您的第三个提示确实很有用,我在我的解决方案中实现了它。对此表示感谢,但是,您的第二个提示存在问题。是否可以将非静态函数作为参数传递?因为我认为这是不可能的 C++,但我不是专家。如果我删除 static ,我会收到此错误。 /Users/onatbas/workspace/cpp/example/main.cpp:24:23: 必须调用非静态成员函数的引用
  • 从您的代码中不清楚它是一个成员函数,如果是,它需要是静态的(在这种情况下)。
【解决方案3】:

您必须将您的typedef 更改为:

typedef void (* MyType)(void *, void *);

(附带说明,它在 VS2013 中运行良好。)

【讨论】:

    猜你喜欢
    • 2013-10-15
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 2015-01-15
    • 2016-06-15
    • 1970-01-01
    相关资源
    最近更新 更多