无法实现接口的[[deprecated]]方法

时间:2016-08-18 16:14:22

标签: c++ visual-c++ visual-studio-2015

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

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

我使用选项将Wanings视为错误(/ 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 ++的错误吗? 有没有办法在Visual Studio中正确使用已弃用的声明?

1 个答案:

答案 0 :(得分:2)

标准说:

  

实现可以使用deprecated属性来生成诊断消息   程序是指除声明之外的名称或实体

IImpl::foo的声明并未引用I::foo

这段文字内容丰富,无需遵循这封信。实际上,一个实现可能会警告你它想要什么。我仍然认为这是一个错误。

它可以像这样解决:

// 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() called\n"; 
    abort(); 
} 

//IImpl.h
#include <IInternal.h>
class IImpl : public I { ... // whatever