Возможная ошибка компилятора в MSVC

13

Следующий код компилируется с помощью gcc и clang (и многих других компиляторов C ++ 11)

#include <stdint.h>

typedef int datatype;

template <typename T>
struct to_datatype {};

template <>
struct to_datatype<int16_t> {
  static constexpr datatype value = 1;
};

template <typename T>
class data {
 public:
  data(datatype dt = to_datatype<T>::value) {}
};

int main() {
  data<char> d{to_datatype<int16_t>::value};
}

когда компилируется с (почти) последним MSVC

> cl .\test.cpp /std:c++latest /permissive-
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
.\test.cpp(16): error C2039: 'value': is not a member of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(16): note: see declaration of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(20): note: see reference to class template instantiation 'data<char>' being compiled

Это ошибка MSVC? Если да, какой термин в стандарте C ++ лучше всего его описывает?

Если вы замените часть кода с

template <typename T>
class data {
 public:
  data(datatype dt) {}
  data() : data(to_datatype<T>::value) {}
};

в любом случае он скомпилируется плавно.

облако
источник
Эта строка может объяснить различия. Посмотрите, что возвращают ваши компиляторы std::is_same_v<char, int8_t>. Я полагаю, что реализация определена так же, как int8_t, как char, но нужно проверить документацию.
alter igel
Похоже, на самом деле это может быть ошибкой. Эта проблема была открыта недавно, и было несколько других сообщений.
измененный экземпляр
1
@alteredinstance Я не понимаю, как эта проблема связана с этим вопросом, или как ваша предыдущая ссылка имеет отношение к этому вопросу. Вы только что скопировали первую ссылку, которую Google дает для этого сообщения об ошибке? Сообщение об ошибке очень общее и может появляться во многих (допустимых) ситуациях.
орех
@walnut Строка 231 кода, упомянутого в этой проблеме, содержит несуществующую ссылку на проблему MSVC с агрегированной инициализацией, то же самое делает код OP. Так уж получилось, что недавно библиотека boost столкнулась с похожей проблемой, value
связанной
1
и новый отчет об ошибке: developercommunity.visualstudio.com/content/problem/871304/…
marcinj

Ответы:

8

Я бы сказал, что MSVC неправильно не принимает код.

Согласно [dcl.fct.default] / 5 окончательного черновика стандарта C ++ 17, поиск имени в аргументах по умолчанию функции-члена шаблона класса выполняется в соответствии с правилами в [temp.inst].

Согласно [temp.inst] / 2 неявное создание экземпляра шаблона класса не вызывает создание экземпляров аргументов по умолчанию для функций-членов, а согласно [temp.inst] / 4 аргумент по умолчанию для функции-члена (неявная специализация а) шаблон класса создается, когда он используется вызовом.

В to_datatype<T>::valueвашем коде нет вызова с использованием аргумента по умолчанию, поэтому его не следует создавать. Поэтому не должно быть ошибка о Lookup из valueв to_datatype<char>отсутствии.

(Соответствующие разделы в окончательном черновом варианте стандарта C ++ 11 имеют эквивалентную формулировку, за исключением нумерации, см. [Decl.fct.default] / 5 , [temp.inst] / 1 и [temp.inst] / 3. )

грецкий орех
источник