Possível bug do compilador no MSVC

13

O código a seguir é compilado com gcc e clang (e muitos outros compiladores 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};
}

ao compilar com o (quase) MSVC mais recente

> 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

Isso é um bug do MSVC? Se sim, qual termo no padrão C ++ o descreve melhor?

Se você substituir parte do código por

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

compila sem problemas de qualquer maneira.

Nuvem
fonte
Este one-liner pode explicar as diferenças. Veja o que seus compiladores retornam std::is_same_v<char, int8_t>. Meu palpite seria que é definido como implementação se int8_t é o mesmo que char, mas seria necessário verificar a documentação.
alter igel
Parece que de fato pode ser um bug. Esse problema foi aberto recentemente e houve vários outros relatórios.
alteredinstance 31/12/19
11
@alteredinstance Não vejo como esse problema se relaciona com essa questão ou como o seu link anterior se relaciona. Você acabou de copiar o primeiro link que o google fornece para esta mensagem de erro? A mensagem de erro é muito genérica e pode aparecer em várias situações (legítimas) diferentes.
Walnut
@walnut A linha 231 do código mencionado no problema possui um link desativado para um problema MSVC com inicialização agregada, a mesma coisa que o código do OP está fazendo. Acontece que recentemente a biblioteca de reforço teve um problema semelhante ao usar valueum tipo agregado no MSVC
alteredinstance
11
e um novo relatório de bug: developercommunity.visualstudio.com/content/problem/871304/…
marcinj 01/01

Respostas:

8

Eu diria que o MSVC está errado em não aceitar o código.

De acordo com [dcl.fct.default] / 5 do rascunho final padrão do C ++ 17, a pesquisa de nome nos argumentos padrão de uma função de membro de um modelo de classe é feita de acordo com as regras em [temp.inst].

De acordo com [temp.inst] / 2 a instanciação implícita de um modelo de classe não causa instanciação de argumentos padrão das funções de membro e de acordo com [temp.inst] / 4 um argumento padrão para uma função de membro de (especialização não explícita de a) o modelo de classe é instanciado quando usado por uma chamada.

Não há chamada usando o argumento padrão to_datatype<T>::valueno seu código e, portanto, não deve ser instanciado. Portanto, não deve haver um erro sobre lookup de valueem to_datatype<char>falhando.

(As seções relevantes no rascunho final padrão do C ++ 11 têm uma redação equivalente, exceto para numeração, consulte [decl.fct.default] / 5 , [temp.inst] / 1 e [temp.inst] / 3. )

noz
fonte