2016-08-18 3 views
3

Я хочу отметить как устаревший какой-либо метод моего интерфейса. Для обратной совместимости мне нужно некоторое время поддерживать старый метод.Невозможно реализовать [[устаревший]] метод интерфейса

// 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?

+0

Какой смысл объявлять функцию '[[устаревшее]]', а затем отключить предупреждение? – nwp

+0

http://stackoverflow.com/a/295229/612920 – Mansuro

+0

@nwp, объявление предназначено для пользователей моего интерфейса. Я поставщик интерфейса. –

ответ

2

Стандарт говорит:

Реализация может использовать устаревший атрибут для получения диагностического сообщения в случае, если программа относится к имени или юридическому лицу, кроме как объявить его

, но заявление от 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