使用std :: enable在Visual Studio 2015上错误C1001

我有一些C ++ 11代码无法在Visual Studio 2015(更新2)上编译,但在Clang和GCC上编译时没有错误。 因此,我怀疑Visual Studio中有一个编译器错误,但也许我的代码有些不合格。

我的真实类BaseUnit是一个超过double值的模板包装类,关注数量的物理尺寸(表示为SI单位m,kg,s,K)。 例如,速度与时间模板实例的相乘会自动给出一个距离实例。 当前实现乘以标量的问题会出现问题。 我尽可能简化班级,以展示问题。

#include <type_traits>

template<int M>
class BaseUnit
{
public:
    constexpr explicit BaseUnit(double aValue) : value(aValue) {}
    template<typename U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0>
        BaseUnit operator*(U scalar) const { return BaseUnit(value * scalar); }
    template<typename U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0>
        friend BaseUnit operator* (U scalar, BaseUnit v) { return BaseUnit(scalar*v.value); }
protected:
    double value;
};

int main()
{
    BaseUnit<1> a(100);
    a = 10 * a;  // <-- error C1001 here
    return 0;
}

在Visual Studio上编译时,无论命令行选项如何,都会出现内部错误C1001:

C:temp>cl bug.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23918 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

bug.cpp
bug.cpp(19): fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1433)
 To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++
 Help menu, or open the Technical Support help file for more information
Internal Compiler Error in C:Program Files (x86)Microsoft Visual Studio 14.0VCBINcl.exe.  You will be prompted to send an error report to Microsoft later.
INTERNAL COMPILER ERROR in 'C:Program Files (x86)Microsoft Visual Studio 14.0VCBINcl.exe'
    Please choose the Technical Support command on the Visual C++
    Help menu, or open the Technical Support help file for more information

从一些实验中,发生错误需要两个operator*定义。 如果删除前缀或后缀版本,示例代码可以很好地编译。

如果这种行为被证实是一个错误,并且不是已知的编译器问题,我可以填写一份关于微软的错误报告。


根据目前的C ++标准草案:

14.1 Template parameters [temp.param]
1 The syntax for template-parameters is:
template-parameter:
   type-parameter
   parameter-declaration
type-parameter:
  type-parameter-key ...opt identifieropt
  type-parameter-key identifieropt= type-id
  template < template-parameter-list > type-parameter-key ...opt identifieropt
  template < template-parameter-list > type-parameter-key identifieropt= id-expression
type-parameter-key:
   class
   typename

结果你有语法错误(你可以报告有关编译器没有检测到这种错误的MS)。 所以在你的情况下,正确的代码是:

template<int M>
class BaseUnit
{
public:
  constexpr explicit BaseUnit(double aValue) : value(aValue) {}
  template<typename U, typename T = typename std::enable_if<std::is_arithmetic<U>::value, int>::type>
  BaseUnit<M> operator*(U scalar) const { return BaseUnit<M>(value * scalar); }
  template<typename U, typename T = typename std::enable_if<std::is_arithmetic<U>::value, int>::type>
  friend BaseUnit operator* (U scalar, BaseUnit v) { return BaseUnit(scalar*v.value); }
protected:
  double value;
};

int main()
{
  BaseUnit<1> a(100);
  a = 10 * a;  // ok
  a = "19" * a;  // error
  return 0;
}
链接地址: http://www.djcxy.com/p/92477.html

上一篇: Error C1001 on Visual Studio 2015 with std::enable

下一篇: Calling a variable stored in a literal notation object