Можлива помилка компілятора в 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
@alteredin substance Я не бачу, як ця проблема стосується цього питання чи як це робить ваше попереднє посилання. Ви просто скопіювали перше посилання, яке 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. )

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.