In another question, in one of the comments, I was informed that this may be non-standard behavior (especially moving up the hierarchy):
struct f1
{
int operator() (int a, int b) const { return a + b; }
};
struct f2
{
int operator() (int a, int b) const { return a * b; }
};
struct f3 : f2
{
typedef f2 base_type;
int operator() (int a, int b) const
{ return base_type::operator()(a,b) * (a / b); }
};
struct f4
{
int operator() (int a, int b) const { return a - b; }
};
struct f5 : f4
{
typedef f4 base_type;
int operator() (int a, int b) const
{ return base_type::operator()(a,b) * a * b; }
};
template <typename F1, typename F3, typename F5>
class foo : F1, F3, F5
{
typedef F1 base_type_1;
typedef F3 base_type_3;
typedef F5 base_type_5;
public:
int f1(int a, int b) { return base_type_1()(a, b); }
int f3(int a, int b) { return base_type_3()(a, b); }
int f5(int a, int b) { return base_type_5()(a, b); }
int f3f2(int a, int b)
{
return base_type_3::base_type::operator()(a, b) *
base_type_3::operator()(a, b);
}
int f5f4(int a, int b)
{
return base_type_5::base_type::operator()(a, b) *
base_type_5::operator()(a, b);
}
};
int main()
{
foo<f1, f3, f5> f;
f.f1(1,2);
f.f3(1,4);
f.f5(1,5);
f.f3f2(1, 1);
f.f5f4(2, 2);
return 0;
}
EDIT: This compiles under VC++ 2008, no warnings at level 4.
I think the case wasn’t clear in ISO/IEC 14882:2003. Although it says:
there is still an open question of what constitutes a class-name:
… and if you look up 7.1.5.3, elaborated-type-specifiers seem to include dependant names, but without explicitly allowing
typedefkeyword. It seems like unintended omission in version 2003 of the standard. Circumstantial evidence: Comeau Compiler in strict mode without C++0x extensions enabled accepts your code.However, using dependant names this way was explicitly made valid in ISO/IEC 14882:2011. Here is relevant wording: