Constexpr作为模板函数中的数组大小(GCC与英特尔)

时间:2017-10-23 07:27:39

标签: c++ c++11 templates constexpr icc

我正在研究用C ++ 11编写的科学代码。此代码的关键操作在3D阵列上执行。这样的数组也经常传递给其他函数。在实现一些新功能的同时,我使用了模板并遇到了以下问题:代码编译很好用gcc 5.4(也经过测试7.2)但是使用英特尔C ++编译器ICC 16.0(也测试了18.0)它没有编译,所以我想知道我是否代码不符合标准,或者其中一个编译器行为不当。

最小的示例代码如下所示(实际上它将是3D数组):

class Constants {   
   static constexpr int value_ = 2;

public:    
   static constexpr inline int V() { return value_; }    
};

typedef Constants CC;

template<int N>
class Terror {    
public:
  template<class T>
  void F(T (&a)[CC::V()]) {}
};

int main() {
  int array[CC::V()];    
  Terror<42> ter = Terror<42>();    
  ter.F(array);
}

我知道传递一个(3D)普通C数组,其大小是通过constexpr确定的,这不是经典的方法,但有理由可以根据需要详细说明。

我尝试阅读C ++ 11标准,但没有找到明确的(至少对我而言)描述我的问题。

ICC抛出的错误是:

main.cpp(15): error: no instance of function template "Terror<N>::F [with N=42]" matches the argument list
            argument types are: (int [2])
            object type is: Terror<42>
   ter.F(array); 
       ^
template_class.h(10): note: this candidate was rejected because at least one template argument could not be deduced
    void F(T (&a)[CC::V()]) {}
         ^

compilation aborted for main.cpp (code 2)

有趣的是,它适用于(3D-)std :: array,或者如果N / T中的两个模板中的一个不存在。

1 个答案:

答案 0 :(得分:4)

这是一个ICC错误。

值得庆幸的是,这是一个非常简单的解决方法,只是将该值存储在Terror中:

template<int N>
class Terror {    
    static constexpr size_t M = CC::V();
public:
    template<class T>
    void F(T (&a)[M]) {}
};

ICC 16和17都接受此更改的程序。