I'm using static functors (to be used everywhere) defined in the base class like:
/* Base.hpp */
class Base {
...
static struct Cpyz_t cpy_z;
};
struct Cpyz_t {
private:
template<typename U>
void op(U& dest, mpz_t& z, std::false_type) {
dest.setz(z);
}
template<typename U>
typename std::enable_if_t<std::is_integral_v<U>,void>
op(U& dest, mpz_t& z, std::true_type) const {
dest = mpz_get_si(z);
}
template<typename U>
typename std::enable_if_t<std::is_floating_point_v<U>,void>
op(U& dest, mpz_t& z, std::true_type) const {
dest = mpz_get_d(z);
}
public:
template<typename U>
void operator()(U& dest, mpz_t& z) {
op(dest, z, std::integral_constant<bool, std::is_arithmetic_v<U>>());
}
};
inline Cpyz_t Base::cpy_z;
The code works well: I can call cpy_z()
from any file (which #includes Base.hpp
). There are many similar functors. I'd like to place the definitions (struct bodies) in the Base.cpp
implementation file, because it's a lot of code. Therefore I'm trying:
/* Base.hpp */
struct Cpyz_t; // forward declaration, incomplete type
class Base {
static struct Cpyz_t cpy_z;
};
/* Base.cpp */
struct Cpyz_t {
/* same as above */
};
Cpyz_t Base::cpy_z;
Now cpy_z()
can be called only from Base.cpp
. When called from somewhere else, e.g.
/* Somewhere.cpp */
#import "Base.hpp"
...
cpy_z(); // compile error
the complainer reports "Incomplete type in call to object of type 'Cpyz_z'"
. I understand what the problem is.
What is the correct syntax to fix it? I can't instantiate a functor variable in Base.hpp
(because the definition follows in Base.cpp
).