Константность вывода шаблона класса C++17

Я пытаюсь использовать вывод нового шаблона класса C++17, и, кажется, все работает нормально, пока я не применю const. Это небольшой пример проблемы, с которой я сталкиваюсь:

#include <type_traits>

template <typename T>
struct X
{
    T _data;

    X(void) = default;
    X(T && data) : _data{ data } {}

    constexpr bool const_x(void) { return false; }
    constexpr bool const_x(void) const { return true; }
};

template <typename T>
X(T &&) -> X<std::remove_reference_t<T>>;

int main(void)
{
    X<int> a;
    const X<int> b{};

    X c{ 10 };
    const X d{ 10 };

    static_assert(!a.const_x());
    static_assert(b.const_x());

    static_assert(!c.const_x());
    static_assert(d.const_x()); // assert fails
}

похоже, что когда const X выводит свои типы, константа не передается. Я знаю, что это возможно:

template <typename T>
X(T &&) -> const X<std::remove_reference_t<X>>;

но это сделало бы каждый выводимый тип const X.

Если у кого-то есть какая-либо информация или помощь, это будет с благодарностью!

РЕДАКТИРОВАТЬ Я использую GCC-7.1.0

1 ответ

Решение

Это ошибка компилятора - в частности, ошибка gcc 80990. Здесь есть две отдельные части - вычет и const, Декларация:

const X d{ 10 };

сначала выполнит вывод аргумента шаблона класса, чтобы выбрать X специализация d есть (так X<int> из-за руководства по удержанию), а затем const добавляется поверх этого (так X<int> const).


Обратите внимание, что это:

template <typename T>
X(T &&) -> const X<std::remove_reference_t<X>>;

плохо сформирован. Вы не можете использовать cv-квалификаторы там.

Другие вопросы по тегам