VC++ 2013: using-declaration + redefinition of member function leads to compile error

▼魔方 西西 提交于 2019-12-12 12:21:39

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!