1

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).

atlantis23
  • 21
  • 3
  • With the second version, the code that includes `Base.hpp` only sees the forward declaration `struct Cpyz_t;`. It can't know that there might be an `operator()`, so `cpy_z()` doesn't make sense. So you need to at least declare the operator in the header. However, that operator is a template, at which point you run into [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Igor Tandetnik Jul 01 '23 at 04:23
  • Yes, that's the problem. Thanks for the comment. I moved the functions to an extra header, which makes more sense anyway. – atlantis23 Jul 08 '23 at 21:43

0 Answers0