不能实现接口的[[deprecated]]方法

Cannot implement [[deprecated]] method of interface

本文关键字:deprecated 方法 实现 接口 不能      更新时间:2023-10-16

我想将我的接口的某些方法标记为已弃用。为了向后兼容,我需要支持旧方法一段时间。

// my own interface for other
interface I {
    [[deprecated( "use 'bar' instead" )]]
    virtual void foo() = 0;
};

但是Visual Studio 2015不允许我实现这个接口:

// my own implementation
class IImpl : public I {
public:
    virtual void foo() override; // here goes warning C4996:
                                 // 'I::foo': was declared deprecated
};

我使用选项将警告视为错误(/WX),因此无法编译此代码。

我尝试在本地忽略警告:

class IImpl : public I {
public:
#pragma warning(push)
#pragma warning(disable: 4996)
    virtual void foo() override;
#pragma warning(pop)
    // ... other methods are outside
};

但是没有效果。允许编译代码的唯一解决方案是忽略整个类声明的警告:

#pragma warning(push)
#pragma warning(disable: 4996)
class IImpl : public I {
public:
    virtual void foo() override;
    // ... other methods are also affected
};
#pragma warning(pop)

GCC似乎使事情变得正确:

#pragma GCC diagnostic error "-Wdeprecated-declarations"
interface I {
    [[deprecated]]
    virtual void foo() = 0;
};
class IImpl : public I {
public:
    virtual void foo() override; // <<----- No problem here
};
int main()
{
    std::shared_ptr<I> i( std::make_shared<IImpl>() );
    i->foo(); // <<---ERROR: 'virtual void I::foo()' is deprecated [-Werror=deprecated-declarations]
    return 0;
}

是msvc++的bug吗?是否有任何方法可以在Visual Studio中正确使用废弃的声明?

标准规定:

实现可以使用不推荐的属性来生成诊断消息程序引用一个名称或实体,而不是声明它

,但IImpl::foo的声明并不是指I::foo

这篇文章内容丰富,不需要严格遵循。实际上,实现可能会警告您它想要的任何东西。但是我仍然认为这是一个bug。

可以这样处理:

// IInternal.h
struct I {
   virtual void foo() = 0; // no deprecation
};
// I.h
#include <IInternal.h>
[[deprecated( "use 'bar' instead" )]]
inline void I::foo() { 
    std::cerr << "pure virtual function I::foo() calledn"; 
    abort(); 
} 
//IImpl.h
#include <IInternal.h>
class IImpl : public I { ... // whatever