首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Visual 2015上使用C1001错误std::enable_if

在Visual 2015上使用C1001错误std::enable_if
EN

Stack Overflow用户
提问于 2016-06-30 18:55:39
回答 1查看 534关注 0票数 7

我有一些C++11代码无法在Visual 2015上编译(更新2),但是编译时Clang和GCC都没有错误。因此,我怀疑Visual中存在编译器错误,但可能我的代码格式不正确。

我真正的类BaseUnitdouble值上的模板包装类,它关注数量的物理维度(以SI单位m、kg、s、K表示)。例如,速度与时间模板实例的乘法自动给出一个距离实例。这个问题发生在当前用标量实现乘法的过程中。我已尽量简化了这门课,以说明问题。

代码语言:javascript
复制
#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上编译时,无论使用什么命令行选项,都会出现一个内部错误C1001:

代码语言:javascript
复制
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.0\VC\BIN\cl.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.0\VC\BIN\cl.exe'
    Please choose the Technical Support command on the Visual C++
    Help menu, or open the Technical Support help file for more information

从一些实验中可以看出,需要两个operator*定义才能出现错误。如果移除前缀或后缀版本,则示例代码可以很好地编译。

如果这个行为被确认为一个bug,而不是一个众所周知的编译器问题,我可能会在Microsoft上填写一个bug报告。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-30 20:14:14

根据现行C++标准草案:

代码语言:javascript
复制
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编译器没有检测到这样的错误)。因此,在您的例子中,正确的格式代码是:

代码语言:javascript
复制
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;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38131189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档