c++ - 编译在我的 Mac 上工作,但不在集群上(Linux)
问题描述
我有一个 c++17 库,可以在我的 Mac 上编译,但不是我大学的集群(Linux)。
我的编译器是:
苹果 clang 版本 11.0.0 (clang-1100.0.33.17)
集群编译器是:
g++ (Spack GCC) 9.2.0
我的一位同事也安装了该库并在其机器(始终是 Mac)上成功编译它。
我试图将所有内容减少到主要(我猜)错误,将所有内容都放在下面的代码中。
这是错误:
error: invalid use of incomplete type 'class TensorBase<double, std::integer_sequence<long unsigned int, 0> >'
116 | class Matrix<Real,1,1,NonZeroRow_>: public TensorBase<Real, std::make_index_sequence<1>>
下面我放代码。我基本上有一个BaseTensor
类Matrix
继承自一个类。我也有一门专业。
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <algorithm>
#include <numeric>
#include <array>
using Integer=long;
using Real=double;
template <typename T, std::size_t>
using getTypeSequence = T;
template <typename, typename>
class TensorBase;
template <typename T, Integer ... Is>
class TensorBase<T, std::index_sequence<Is...>>
{
protected:
std::array<T, sizeof...(Is)> values{};
static const std::size_t Size = sizeof...(Is);
public:
constexpr TensorBase (getTypeSequence<T, Is> ... vals)
: values{{vals...}}
{}
constexpr TensorBase (std::array<T, sizeof...(Is)> const & a)
: values{a}
{}
constexpr TensorBase (std::array<T, sizeof...(Is)> && a)
: values{std::move(a)}
{}
// TensorBase(std::initializer_list<T> a)
// {
// assert(a.size() == Size);
// std::copy(std::begin(a), std::end(a), std::begin(values));
// }
constexpr TensorBase () = default;
~TensorBase() = default;
constexpr TensorBase (TensorBase const &) = default;
constexpr TensorBase (TensorBase &&) = default;
constexpr TensorBase & operator= (TensorBase const &) = default;
constexpr TensorBase & operator= (TensorBase &&) = default;
};
template<typename T, Integer Rows_, Integer Cols_,Integer NonZeroRow_=-1>
class Matrix: public TensorBase<T, std::make_index_sequence<Rows_*Cols_>>
{
public:
static constexpr Integer Rows=Rows_;
static constexpr Integer Cols=Cols_;
using type= Matrix<T,Rows,Cols>;
using subtype=T;
using MB = TensorBase<T, std::make_index_sequence<Rows*Cols>>;
using MB::MB;
using MB::values;
static constexpr Integer NonZeroRow=NonZeroRow_;
inline constexpr static Integer rows() { return Rows; }
inline constexpr static Integer cols() { return Cols; }
inline constexpr std::array<T,Rows*Cols> &operator()()
{
return values;
}
inline constexpr const std::array<T,Rows*Cols> &operator()()const
{
return values;
}
// access matrix direclty by using I*Col+J index
inline constexpr T &operator()(const Integer i)
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr const T &operator()(const Integer i)const
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr T &operator()(const Integer i, const Integer j)
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
inline constexpr const T &operator()(const Integer i, const Integer j) const
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
};
template<Integer NonZeroRow_>
class Matrix<Real,1,1,NonZeroRow_>: public TensorBase<Real, std::make_index_sequence<1>>
{
public:
static constexpr Integer Rows=1;
static constexpr Integer Cols=1;
using T= Real;
using type= Matrix<T,Rows,Cols>;
using subtype=T;
using MB = TensorBase<T, std::make_index_sequence<Rows*Cols>>;
using MB::MB;
using MB::values;
static constexpr Integer NonZeroRow=NonZeroRow_;
inline constexpr static Integer rows() { return Rows; }
inline constexpr static Integer cols() { return Cols; }
inline constexpr std::array<T,Rows*Cols> &operator()()
{
return values;
}
inline constexpr const std::array<T,Rows*Cols> &operator()()const
{
return values;
}
inline constexpr T &operator[](const Integer i)
{
assert(i < Rows);
return values[i];
}
inline constexpr T &operator[](const Integer i)const
{
assert(i < Rows);
return values[i];
}
// access matrix direclty by using I*Col+J index
inline constexpr T &operator()(const Integer i)
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr const T &operator()(const Integer i)const
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr T &operator()(const Integer i, const Integer j)
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
inline constexpr const T &operator()(const Integer i, const Integer j) const
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
};
int main(int argc, char *argv[])
{
constexpr Matrix<Real,1,1> mat{1.0};
std::cout<<"it works"<<std::endl;
static_assert(mat(0,0)==1.0);
return 0;
}
解决方案
在 gcc 10.1 中使用integer_sequence<Integer, Is...>
代替index_sequence<Is...>
并将 const 添加到 in 的返回中operator[]
为Matrix<Real,1,1,NonZeroRow_>
我修复了构建错误。我真的不知道为什么使用整数序列来解决问题,但除了修复构建错误之外,在这种情况下行为应该是等效的。
这是在我进行编辑后编译的版本https://godbolt.org/z/dKHLDB
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <algorithm>
#include <numeric>
#include <array>
using Integer=long;
using Real=double;
template <typename T, std::size_t>
using getTypeSequence = T;
template <typename, typename>
class TensorBase;
template <typename T, Integer ... Is>
class TensorBase<T, std::integer_sequence<Integer, Is...>>
{
protected:
std::array<T, sizeof...(Is)> values{};
static const std::size_t Size = sizeof...(Is);
public:
constexpr TensorBase (getTypeSequence<T, Is> ... vals)
: values{{vals...}}
{}
constexpr TensorBase (std::array<T, sizeof...(Is)> const & a)
: values{a}
{}
constexpr TensorBase (std::array<T, sizeof...(Is)> && a)
: values{std::move(a)}
{}
// TensorBase(std::initializer_list<T> a)
// {
// assert(a.size() == Size);
// std::copy(std::begin(a), std::end(a), std::begin(values));
// }
constexpr TensorBase () = default;
~TensorBase() = default;
constexpr TensorBase (TensorBase const &) = default;
constexpr TensorBase (TensorBase &&) = default;
constexpr TensorBase & operator= (TensorBase const &) = default;
constexpr TensorBase & operator= (TensorBase &&) = default;
};
template<typename T, Integer Rows_, Integer Cols_,Integer NonZeroRow_=-1>
class Matrix: public TensorBase<T, std::make_integer_sequence<Integer, Rows_*Cols_>>
{
public:
static constexpr Integer Rows=Rows_;
static constexpr Integer Cols=Cols_;
using type= Matrix<T,Rows,Cols>;
using subtype=T;
using MB = TensorBase<T, std::make_integer_sequence<Integer, Rows*Cols>>;
using MB::MB;
using MB::values;
static constexpr Integer NonZeroRow=NonZeroRow_;
inline constexpr static Integer rows() { return Rows; }
inline constexpr static Integer cols() { return Cols; }
inline constexpr std::array<T,Rows*Cols> &operator()()
{
return values;
}
inline constexpr const std::array<T,Rows*Cols> &operator()()const
{
return values;
}
// access matrix direclty by using I*Col+J index
inline constexpr T &operator()(const Integer i)
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr const T &operator()(const Integer i)const
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr T &operator()(const Integer i, const Integer j)
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
inline constexpr const T &operator()(const Integer i, const Integer j) const
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
};
template<Integer NonZeroRow_>
class Matrix<Real,1,1,NonZeroRow_>: public TensorBase<Real, std::make_integer_sequence<Integer,1>>
{
public:
static constexpr Integer Rows=1;
static constexpr Integer Cols=1;
using T= Real;
using type= Matrix<T,Rows,Cols>;
using subtype=T;
using MB = TensorBase<T, std::make_integer_sequence<Integer,Rows*Cols>>;
using MB::MB;
using MB::values;
static constexpr Integer NonZeroRow=NonZeroRow_;
inline constexpr static Integer rows() { return Rows; }
inline constexpr static Integer cols() { return Cols; }
inline constexpr std::array<T,Rows*Cols> &operator()()
{
return values;
}
inline constexpr const std::array<T,Rows*Cols> &operator()()const
{
return values;
}
inline constexpr T &operator[](const Integer i)
{
assert(i < Rows);
return values[i];
}
inline constexpr const T &operator[](const Integer i)const
{
assert(i < Rows);
return values[i];
}
// access matrix direclty by using I*Col+J index
inline constexpr T &operator()(const Integer i)
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr const T &operator()(const Integer i)const
{
assert(i < Rows*Cols);
return values[i];
}
inline constexpr T &operator()(const Integer i, const Integer j)
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
inline constexpr const T &operator()(const Integer i, const Integer j) const
{
assert(i < Rows);
assert(j < Cols);
return values[i*cols() + j];
}
};
int main(int argc, char *argv[])
{
constexpr Matrix<Real,1,1> mat{1.0};
std::cout<<"it works"<<std::endl;
static_assert(mat(0,0)==1.0);
return 0;
}
以下是具体变化:
前
template <typename T, Integer ... Is>
class TensorBase<T, std::index_sequence<Is...>>
后
template <typename T, Integer ... Is>
class TensorBase<T, std::integer_sequence<Integer, Is...>>
前
template<typename T, Integer Rows_, Integer Cols_,Integer NonZeroRow_=-1>
class Matrix: public TensorBase<T, std::make_index_sequence<Rows_*Cols_>>
后
template<typename T, Integer Rows_, Integer Cols_,Integer NonZeroRow_=-1>
class Matrix: public TensorBase<T, std::make_integer_sequence<Integer, Rows_*Cols_>>
之前(在Matrix
)
using MB = TensorBase<T, std::make_index_sequence<Rows*Cols>>;
后
using MB = TensorBase<T, std::make_integer_sequence<Integer, Rows*Cols>>;
前
template<Integer NonZeroRow_>
class Matrix<Real,1,1,NonZeroRow_>: public TensorBase<Real, std::make_index_sequence<1>>
后
template<Integer NonZeroRow_>
class Matrix<Real,1,1,NonZeroRow_>: public TensorBase<Real, std::make_integer_sequence<Integer, 1>>
之前(在Matrix<Real,1,1,NonZeroRow_>
)
using MB = TensorBase<T, std::make_index_sequence<Rows*Cols>>;
后
using MB = TensorBase<T, std::make_integer_sequence<Integer, Rows*Cols>>;
之前(在Matrix<Real,1,1,NonZeroRow_>
)
inline constexpr T &operator()(const Integer i)const
后
inline constexpr const T &operator()(const Integer i)const
推荐阅读
- python - 如何连接字典的所有键和值并以字符串的形式返回?
- java - 在 Java 中的多线程套接字编程方面需要帮助
- javascript - 在javascript中将三元运算分解为if,else
- javascript - 如何修复错误:对象作为 React 子对象无效(找到:[object Promise])
- javascript - 为 HTML 表单生成安全随机数
- php - woocmmerce 函数类的选择选项上的 foreach 数组存在问题
- c - Linux从_start获取终端参数不适用于C中的内联汇编
- flutter - 尝试将小部件添加到小部件列表
- f# - 读取与 f# 中的元组在同一行中的两个整数
- java - 如何生成两个数组的组合?