【发布时间】:2015-08-01 21:29:11
【问题描述】:
我在一个较大程序的某个部分遇到问题,我想说的不是模棱两可的东西被 g++ 和 clang++ 认为是模棱两可的
#include <functional>
#include <string>
struct Foo {
Foo(int) {}
Foo(std::string) {}
operator int () const { return 42; }
operator std::string () const { return ""; }
void foo(std::function<void(Foo&, int)>f);
void foo(std::function<void(const Foo&, int)>f) const; // xxx
void foo(std::function<void(const std::string&, Foo&)>f);
void foo(std::function<void(const std::string&, const Foo&)>f) const;
void bar() const {
this->foo([](const Foo&, int){}); // xxx
}
};
我希望在 bar 中调用的 ::foo 能够明确解析为标有 xxx 的 const 版本,而两个编译器都抱怨重载解析不明确:
g++ -std=c++11 -c -Wall amb.cpp
amb.cpp: In member function ‘void Foo::bar() const’:
amb.cpp:18:40: error: call of overloaded ‘foo(Foo::bar() const::<lambda(const Foo&, int)>)’ is ambiguous
this->foo([](const Foo&, int){});
^
amb.cpp:12:10: note: candidate: void Foo::foo(std::function<void(const Foo&, int)>) const
void foo(std::function<void(const Foo&, int)>f) const;
^
amb.cpp:15:10: note: candidate: void Foo::foo(std::function<void(const std::basic_string<char>&, const Foo&)>) const
void foo(std::function<void(const std::string&, const Foo&)>f) const;
^
为什么不清楚我要调用哪个版本?我该如何解决这个问题?
【问题讨论】:
-
查看
std::function的构造函数约束。这两个命名的重载都是允许的。两者都产生用户定义的转换,没有一个比另一个更好。 -
@KerrekSB:我不确定我是否理解。标记的版本有一个 相同 std::function 参数声明,其他版本没有。为什么这也被视为用户定义的转换?
-
您的函数参数是一个 lambda 表达式,而不是
std::function<void(const Foo&, int)>类型的表达式。所以你需要一个转换。
标签: c++11 overloading std-function const-correctness