c++ - 漏洞?当数组具有模板大小时,为什么我不能在数组成员上使用模板函数
问题描述
问题
这是我经历过的最奇怪的事情。3小时后,我设法将其归结为这个可重现的示例(下面的代码,如果有点乱,对不起,我尽力了)
我用评论标记了这一行。请不要,上面的一行不是问题。我还为 Test 结构提供了一些其他定义。如果我替换 MWE 中提供的那个,那么它可以完美地编译。最值得注意的是,我可以分配weights[0]
给A
然后调用A.applyFunction<float>(...)
. 那么 g++ 是什么原因,它不喜欢我的数组元素呢?我首先想到,这可能是由于模板大小,事实上,如果我用固定大小替换它,它就会编译。但是, thenA=weights[0]
也不应该工作。我真的很好奇,会有什么解释。
错误信息
g++ -o test -c test.cpp -O0 -ggdb -DDEBUG -D__DEBUG -Wextra -Wshadow -Wconversion -Werror -Wall
test.cpp: In constructor ‘Test<sz>::Test()’:
test.cpp:79:43: error: expected primary-expression before ‘float’
79 | weights[0] = weights[0].applyFunction<float>(test);
| ^~~~~
test.cpp:79:43: error: expected ‘;’ before ‘float’
79 | weights[0] = weights[0].applyFunction<float>(test);
编译器信息:
g++ --version g++ (Ubuntu 9-20190428-1ubuntu1~18.04.york0) 9.0.1 20190428 (prerelease) [gcc-9-branch revision 270630] 版权所有 (C) 2019 Free Software Foundation, Inc. 这是免费软件;查看复制条件的来源。没有保修;甚至不考虑适销性或特定用途的适用性。
代码
#include <algorithm>
#include <array>
#include <cstdio>
#include <functional>
#include <iostream>
#include <iterator>
#include <ostream>
#include <stdexcept>
namespace Math{
template<typename R>
struct Matrix{
private: unsigned short nRows, nCols;
public:
R* data;
Matrix<R>() : nRows(0), nCols(0){}
Matrix<R>(unsigned short nRows_, unsigned short nCols_) : Matrix<R>(nRows_, nCols_, R{}){
}
Matrix<R>(unsigned short nRows_, unsigned short nCols_, const R& val) : nRows(nRows_),nCols(nCols_){
data = new R[nRows * nCols];
for( unsigned short i = 0; i < nRows; ++i ){
for( unsigned short j = 0; j < nCols; ++j ){
data[i*nCols+j] = val;
}
}
}
Matrix<R>(unsigned short nCols_, unsigned short nRows_, R* vals) : nRows(nRows_), nCols(nCols_){
data = new R[nRows * nCols];
std::copy(vals, vals+nRows*nCols, data);
}
~Matrix<R>(){
delete[] data;
}
Matrix<R>(const Matrix<R>& m) : nRows(m.nRows), nCols(m.nCols){
data = new R[nRows * nCols];
data = m.data;
}
Matrix<R>& operator=(const Matrix<R>& m){
nRows = m.getNumRows();
nCols = m.getNumCols();
data = new R[nRows * nCols];
std::copy(m.data, m.data+nRows*nCols, data);
return *this;
}
template<typename S>
Matrix<S> applyFunction(std::function<S(R)> f){
Matrix<S> result(nCols, nRows);
for( unsigned short i = 0; i < nRows; ++i ){
for( unsigned short j = 0; j < nCols; ++j ){
result.data[i*nCols+j] = f(data[i*nCols+j]);
}
}
return result;
}
unsigned short getNumCols() const{
return nCols;
}
unsigned short getNumRows() const{
return nRows;
}
};
}
float test(float x){return x*x;}
using Math::Matrix;
template<unsigned short sz>
struct Test{
std::array<Matrix<float>, sz+1> weights;
Test(){
Matrix<float> A;
A = Matrix<float>(2, 2, 0.132f);
weights[0] = Matrix<float>(2, 2, 0.132f);
A = A.applyFunction<float>(test);
weights[0] = weights[0].applyFunction<float>(test); /* Line 79 */
}
};
int main(){
Test<2> t;
}
测试#2(有效)
template<unsigned short sz>
struct Test{
std::array<Matrix<float>, sz+1> weights;
Test(){
Matrix<float> A;
A = Matrix<float>(2, 2, 0.132f);
weights[0] = Matrix<float>(2, 2, 0.132f);
A = weights[0];
A = A.applyFunction<float>(test);
// weights[0] = weights[0].applyFunction<float>(test);
}
};
测试#3(有效)
template<unsigned short sz>
struct Test{
std::array<Matrix<float>, 3> weights;
Test(){
Matrix<float> A;
A = Matrix<float>(2, 2, 0.132f);
weights[0] = Matrix<float>(2, 2, 0.132f);
A = A.applyFunction<float>(test);
weights[0] = weights[0].applyFunction<float>(test);
}
};
解决方案
推荐阅读
- javascript - 对象在 JavaScript 中的工作原理
- r - 将新元素(标签)添加到 R 中的列表中
- r - 将适当的子集四分位数附加到数据集
- hibernate - 在 Hibernate 中调用 merge() 方法
- javascript - 如何使用查询选择器单击
- docker - 无法在 Windows 上使用 Toolbox 在代理后面运行 pull Docker Image
- angular - IONIC4 当我们从一页转到另一页并在 ios 中返回显示空白页时
- ios - 禁用特定 UIView iOS 12 的自动旋转
- html - 谷歌浏览器最新版本,73.0,网页应用溢出不再起作用
- c++ - 检查字符串单词是否包含数字且不包含数字