问题
I want to allow to modify behaviour of my class by specifing policy. This policy shoud be used as visitor for boost::variant. There is default policy that fits most cases good, but user may need to add or replace some overloads.
I found that vc++ 2013 doesn't compile this code with error C3066: there are multiple ways that an object of this type can be called with these arguments
. Same code compiles and works as expected in gcc and clang.
Is it vc++ 2013 bug?
#include <iostream>
struct DefaultPolicy
{
void operator()( bool ) { std::cout << "Base: bool" << std::endl; }
void operator()( int ) { std::cout << "Base: int" << std::endl; }
};
struct UserModifiedPolicy : public DefaultPolicy
{
using DefaultPolicy::operator();
void operator()( int ) { std::cout << "Derived: int" << std::endl; }
void operator()( float ) { std::cout << "Derived: float" << std::endl; }
};
int main()
{
UserModifiedPolicy()(true);
UserModifiedPolicy()(1); // <-- ERROR HERE
UserModifiedPolicy()(1.f);
return 0;
}
UPD This exaple works in vc++ 2010. Looks like it is a bug in 2013 version.
UPD Workaround
#include <iostream>
struct DefaultPolicy
{
void operator()( bool ) { std::cout << "Base: bool" << std::endl; }
void operator()( int ) { std::cout << "Base: int" << std::endl; }
};
struct UserModifiedPolicy : public DefaultPolicy
{
// Using template to forward a call to the base class:
template< class T >
void operator()( T && t ) { DefaultPolicy::operator()( std::forward<T>(t) ); }
void operator()( int ) { std::cout << "Derived: int" << std::endl; }
void operator()( float ) { std::cout << "Derived: float" << std::endl; }
};
int main()
{
UserModifiedPolicy()(true);
UserModifiedPolicy()(1);
UserModifiedPolicy()(1.f);
return 0;
}
回答1:
The code is well-formed. 7.3.3/15:
When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).
So UserModifiedPolicy::operator()(int)
should still hide DefaultPolicy::operator()(int)
. And name lookup for operator()
should find the three members DefaultPolicy::operator()(bool)
, UserModifiedPolicy::operator()(int)
, and UserModifiedPolicy::operator()(float)
.
来源:https://stackoverflow.com/questions/24409307/vc-2013-using-declaration-redefinition-of-member-function-leads-to-compile