编译在我的 Mac 上工作,但在集群上不工作 (Linux)
Compilation working on my Mac but not on the cluster (Linux)
我有一个 c++17 的库,它在我的 Mac 上编译,但不是我大学的集群 (Linux)。
我的编译器是:
Apple 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
class 继承自 class Matrix
。这样的class我也有专攻
#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;
}
使用 integer_sequence<Integer, Is...>
而不是 index_sequence<Is...>
并在 Matrix<Real,1,1,NonZeroRow_>
中的 operator[]
的 return 中添加 const 为我修复了 gcc 10.1 中的构建错误。我真的不知道为什么使用整数序列来解决问题,但除了修复构建错误之外,在这种情况下行为应该是等效的。
这是我编辑后编译的版本 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
我有一个 c++17 的库,它在我的 Mac 上编译,但不是我大学的集群 (Linux)。
我的编译器是:
Apple 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
class 继承自 class Matrix
。这样的class我也有专攻
#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;
}
使用 integer_sequence<Integer, Is...>
而不是 index_sequence<Is...>
并在 Matrix<Real,1,1,NonZeroRow_>
中的 operator[]
的 return 中添加 const 为我修复了 gcc 10.1 中的构建错误。我真的不知道为什么使用整数序列来解决问题,但除了修复构建错误之外,在这种情况下行为应该是等效的。
这是我编辑后编译的版本 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