【问题标题】:VC++ 2013: using-declaration + redefinition of member function leads to compile errorVC++ 2013:使用声明+重新定义成员函数导致编译错误
【发布时间】:2014-06-25 12:56:53
【问题描述】:

我想允许通过指定策略来​​修改我的班级的行为。此策略应用作 boost::variant 的访问者。有适合大多数情况的默认策略,但用户可能需要添加或替换一些重载。

我发现 vc++ 2013 编译此代码时出现错误C3066: there are multiple ways that an object of this type can be called with these arguments。在 gcc 和 clang 中,相同的代码可以按预期编译和工作。

是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 这个例子在 vc++ 2010 中工作。看起来它是 2013 版本中的一个错误。


UPD 解决方法

#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;
}

【问题讨论】:

  • 哪个调用产生了错误?
  • 什么版本的vc++?
  • UserModifiedPolicy()(1); // 此处出错(int 重载)

标签: c++ visual-c++-2013


【解决方案1】:

代码格式正确。 7.3.3/15:

using-declaration 将基类中的名称带入派生类范围时,派生类中的成员函数和成员函数模板会覆盖和/或隐藏成员函数和成员函数模板基类中的相同名称、参数类型列表 (8.3.5)、cv-qualification 和 ref-qualifier(如果有)(而不是冲突)。

所以UserModifiedPolicy::operator()(int) 仍应隐藏DefaultPolicy::operator()(int)operator() 的名称查找应该找到三个成员 DefaultPolicy::operator()(bool)UserModifiedPolicy::operator()(int)UserModifiedPolicy::operator()(float)

【讨论】:

    猜你喜欢
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 2022-11-14
    • 2023-03-16
    • 1970-01-01
    • 2022-11-25
    • 2012-09-03
    相关资源
    最近更新 更多