cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
90 stars 0 forks source link

Разрешить полную специализацию шаблонов внутри классов (explicit specialization in non-namespace scope) #322

Closed apolukhin closed 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +13, -0 Автор идеи: Amomum

Сейчас этого делать нельзя, хотя в некоторых компиляторах можно (и никто не умирает). Причем частичная специализация почему-то разрешена. Считаю, что никакого смысла в этом нет, обходные пути более многословны и уродливы.

Сейчас подобный код не компилируется с не очень внятной ошибкой:

class A
{
    private:

    template< typename T>
    class Inner
    {
        T value;
    };

    template<>
    class Inner<int>
    {
        int value;
    };
};
error: "explicit specialization in non-namespace scope 'class A'"

Простое решение - сделать специализацию частичной, добавив фейковый параметр Dummy:

class A
{
    private:

    template< typename T, typename Dummy = void>
    class Inner
    {
        T value;
    };

    template< typename Dummy>
    class Inner< int, Dummy >
    {
        int value;
    };
};

Однако такой код длиннее и менее понятен. К тому же, частичная специализация невозможна для шаблонных методов, которые страдают от той же проблемы. Следует так же отметить, что некоторые компиляторы (в частности, MSVC) компилируют первый сниппет вопреки стандарту - и вроде как полет нормальный.

Причины, по которым стандарт это запрещает, неясны.

Предлагаю разрешить.

apolukhin commented 3 years ago

Антон Санаров, 26 июля 2018, 12:48 Стандарт это уже разрешает: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#727. Изменение включено в C++17 и бэкпортировано на C++14.

GCC, к сожалению, пока не поддерживает подобные объявления. На эту тему открыт баг-репорт https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282