Константность вывода шаблона класса 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-квалификаторы там.