4

我想允许通过指定策略来​​修改我的班级的行为。此策略应用作 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 错误吗?

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

1 回答 1

2

代码格式正确。7.3.3/15:

using-declaration将基类中的名称带入派生类范围时,派生类中的成员函数和成员函数模板会覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,parameter-type-list (8.3 .5)、cv-qualification 和ref-qualifier(如果有)在基类中(而不是冲突)。

所以UserModifiedPolicy::operator()(int)还是应该躲起来DefaultPolicy::operator()(int)。并且名称查找operator()应该找到三个成员DefaultPolicy::operator()(bool),UserModifiedPolicy::operator()(int)UserModifiedPolicy::operator()(float)

于 2014-06-25T13:15:54.630 回答