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的一个bug吗?如果是,C++标准中哪个术语最能描述它?
如果你用以下代码替换部分代码:
template <typename T>
class data {
 public:
  data(datatype dt) {}
  data() : data(to_datatype<T>::value) {}
};

无论如何,它都可以顺利编译。


看起来这可能实际上是一个 bug。这个问题 最近被提出,并且已经有几个其他报告了。 - alteredinstance
1
@alteredinstance 我不明白那个问题与这个问题有什么关系,或者说你之前的链接与此有何关联。你只是复制了谷歌给出的第一个错误信息链接吗?这个错误信息非常通用,可能会在许多不同(合法的)情况下出现。 - walnut
@walnut 在问题中提到的代码的第231行(https://github.com/boostorg/proto/blob/develop/include/boost/proto/generate.hpp)链接到一个已经失效的MSVC问题,该问题与OP的代码正在做的事情相同。恰好,boost库最近也遇到了类似的问题,在使用MSVC时使用“value”作为聚合类型。 - alteredinstance
@alteredinstance OP没有进行任何聚合初始化。data不是聚合类型,因为它具有用户提供的构造函数。根据链接名称,引用的问题是代码生成问题,而不是前端问题,这会导致编译错误,就像这里一样。我已经在下面发布了一个答案来回答这个问题。这里的问题是默认参数是否应该被实例化。如果它被实例化,那么错误消息是正确的。否则就不是。 - walnut
1
还有一个新的错误报告:https://developercommunity.visualstudio.com/content/problem/871304/vc-2019-default-arguments-of-member-function-are-m.html - marcinj
显示剩余5条评论
1个回答

8
我认为MSVC不接受这段代码是错误的。
根据C++17标准草案中的[dcl.fct.default]/5,类模板成员函数的默认参数名称查找遵循[temp.inst]中的规则。
根据[temp.inst]/2,类模板的隐式实例化不会导致成员函数的默认参数实例化。根据[temp.inst]/4,(非显式类模板特化的)类模板成员函数的默认参数在调用时使用时实例化。
您的代码中没有使用默认参数to_datatype<T>::value的调用,因此不应该实例化它。因此,关于在to_datatype<char>中查找value失败的错误不应该出现。
(C++11标准最终草案中相关部分的措辞相同,除了编号外,请参见[decl.fct.default]/5, [temp.inst]/1[temp.inst]/3。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接