std::function 复制运算符的奇怪行为 (MSVC2012)

Odd behaviour of std::function copy operator (MSVC2012)

我 运行 在尝试使用 function<> 对象时出现 bad_function_call 异常问题。

发现问题后我进入下一个简单示例: http://ideone.com/Mwvw7s

主要摘录:

std::function<void(void*)> f1;
std::function<void(const void*)> f2;
f1 = f2; // Could fail, but didn't

if(f1)
    f1(nullptr); // Should never run
else 
    std::cout << "Skip f1" << std::endl; // Should run

if(f2)
    f2(nullptr);
else 
    std::cout << "Skip f2" << std::endl;

这样f1就生效了,不管f2。 此问题仅在 MSVC2012 上出现(未尝试任何其他版本的 MS 编译器)并且在 GCC 中按预期工作。

问题是:

  1. 这个问题是MSVC2012特有的吗? (任何人都可以在 MSVC2013 上测试)
  2. 这个问题是众所周知的吗?
  3. [如果1和2是'no']我该投诉谁呢?

更新

  1. MSVC2013 不会重现此类问题。
  2. 以防万一有人关心,GitHub 存储库有问题:https://github.com/comargo/functional_test

这似乎是 MSVC2012 的问题; MSVC2013 运行正确 (live example).

function class 模板实例化实例的分配来自模板的不同实例化(即具有不同的签名)委托给构造函数,并由 [= 的特殊子句处理27=][func.wrap.func.con]:

8 - Postconditions: !*this if any of the following hold: [...]

  • F is an instance of the function class template, and !f

我猜测库实现者未能为 MSVC2012 实现此子句;在 function class 模板实例之间进行转换时,最直接的策略是将源类型包装在转换包装器中;很容易忘记检查源实例是否已使用。

作为解决方法,您可以编写:

f2 ? (f1 = f2) : (f1 = nullptr);