我正在研究用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中的两个模板中的一个不存在。
答案 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都接受此更改的程序。