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相同,是由实现定义的,但是需要检查文档。
Igel

看起来实际上可能是一个错误。这个问题是最近开放的,还有其他一些报告。
alteredinstance

1
@alteredinstance我看不到这个问题与这个问题有什么关系,或者您以前的链接是怎么回事。您是否只是复制了Google为该错误消息提供的第一个链接?该错误消息非常笼统,可能出现在许多不同的(合法)情况下。
胡桃木

该问题中提到的代码的 @walnut 第231行具有已终止的指向具有聚合初始化的MSVC问题的链接,这与OP的代码正在做的事情相同。碰巧的是,boost库最近value在使用MSVC的聚合类型时也遇到了类似的问题
alteredinstance

Answers:


8

我想说MSVC不接受代码是错误的。

根据C ++ 17标准最终草案的[dcl.fct.default] / 5,根据[temp.inst]中的规则在类模板的成员函数的默认参数中进行名称查找。

根据[temp.inst] / 2,类模板的隐式实例化不会导致实例化成员函数的默认参数,根据[temp.inst] / 4,成员模板的成员函数的默认参数(非显式专业化) a)类模板在被调用使用时被实例化。

to_datatype<T>::value在代码中没有使用默认参数的调用,因此不应实例化它。因此不应该有关于查找错误valueto_datatype<char>失败。

(C ++ 11标准最终草案中的相关部分具有相同的措词,除了编号外,请参见[decl.fct.default] / 5[temp.inst] / 1[temp.inst] / 3。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.