和Lambdas一起玩,我发现了一个我不完全理解的有趣行为.
我有一个struct Overload派生自2个模板参数,并有一个using F1::operator();子句.
现在,如果我从两个函子派生,我只能访问F1的operator()(正如我所料)
如果我从两个Lambda函数派生,则不再适用:我也可以从F2访问operator().
#include <iostream>
// I compiled with g++ (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
//
// g++ -Wall -std=c++11 -g main.cc
// g++ -Wall -std=c++11 -DFUNCTOR -g main.cc
//
// or clang clang version 3.3 (tags/RELEASE_33/rc2)
//
// clang++ -Wall -std=c++11 -g main.cc
// clang++ -Wall -std=c++11 -DFUNCTOR -g main.cc
//
// on a Linux localhost.localdomain 3.9.6-200.fc18.i686 #1 SMP Thu Jun 13
// 19:29:40 UTC 2013 i686 i686 i386 GNU/Linux box …Run Code Online (Sandbox Code Playgroud) 考虑以下课程:
class Foo
{
public:
void operator [] (const std::string& s) { }
void operator [] (std::size_t idx) { }
};
Run Code Online (Sandbox Code Playgroud)
这里,给定一个实例Foo f,表达式f[0]不含糊,因为编译器选择第二个重载.同样,表达式f["abc"]不含糊,因为编译器选择第一个重载(因为a const char*可以转换为a std::string).
那么,为什么呢,如果我们有两个Base类,每个都有不同的重载,那么突然有歧义?
假设我们有:
class Base1
{
public:
void operator [] (const std::string& s) { }
};
class Base2
{
public:
void operator [] (std::size_t idx) { }
};
class Derived : public Base1, public Base2
{ };
Run Code Online (Sandbox Code Playgroud)
现在,如果我们说:
Derived d;
d[0];
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
error: request for member ‘operator[]’ …Run Code Online (Sandbox Code Playgroud)