How to remove classes while keeping deprecation warnings

I am trying to find a good way to remove obsolete classes from my library, while maintaining good error messages. This idea is based on what I am already doing with functions:

namespace
{
    [[deprecated("This function has been replaced by combust()")]]
    void explode() = delete; // Using variadic templates in reality to have all signatures covered

    void combust() {}
}

int main()
{
    explode();
    combust();
}

In clang, this gives me a nice error message:

<source>:11:2: error: call to deleted function 'explode': This function has been replaced by combust()
explode();
^~~~~~~

GCC only gives me a message stating that this feature has been removed. Although, it still shows intent for anyone trying to update a library that ignored the obsolescence warning.

So, since this is a C ++ library, I basically have classes, and I'm looking for the right way to do something similar with these classes. My current approach is as follows:

namespace
{
    class [[deprecated("Class has been replaced by Bar")]] Foo
    {
        Foo () = delete; // And every other method I had in this class
    };
    class Bar
    {
    };
}

int main()
{
    Foo f;
    Bar b;
}

This basically gives me the following warnings / errors in clang (and similar in GCC):

<source>:13:5: warning: 'Foo' is deprecated: Class has been replaced by Bar [-Wdeprecated-declarations]
Foo f;
^
<source>:3:60: note: 'Foo' has been explicitly marked deprecated here
class [[deprecated("Class has been replaced by Bar")]] Foo
^
<source>:13:9: error: call to deleted constructor of '(anonymous namespace)::Foo'
Foo f;
^
<source>:5:8: note: 'Foo' has been explicitly marked deleted here
Foo () = delete;
^

, , , .

, , : ( )

class [[deprecated("Class has been replaced by Bar")]] Foo = delete;

oneliner:

struct [[deprecated("Class has been replaced by Bar")]] Foo { Foo() = delete; };
struct [[deprecated("Class has been replaced by Bar")]] Foo;

, , Foo .

- ?

+4
1

static_assert, . , , . , , , . , , .

template <int I = 0>
void explode()
{
    static_assert(I && false, "This function has been replaced by combust()");
}

int main()
{
    // error: static_assert failed: "This function has been replaced by combust()"
    explode();
}

. , typedef, .

namespace
{
    template <int I = 0>
    class FooDeprec
    {
        static_assert(I && false, "Class has been replaced by Bar");

        FooDeprec() = default; // no need to delete
    };

    using Foo = FooDeprec<>;
}

int main()
{
    // error: static_assert failed "Class has been replaced by Bar"
    Foo f;
}

, - -.

+1

Source: https://habr.com/ru/post/1666830/


All Articles