Здравствуйте, rg45, Вы писали:
R>Придурок, это классическая проблема, с которой сталкивался каждый, кто использует идиoму скрытой реализации (PImpl). Это только для тебя это является открытием.
Я все же думаю, что здесь ситуация несколько хитрее.
Вот что придумалось:
Файл demo.hpp
// demo.hpp
#pragma once
#include <memory>
class Class2;
class Class1 {
template<typename C>
static int get_v() {
C v;
return v.value();
}
int v_{ get_v<Class2>() };
public:
Class1();
~Class1();
static std::unique_ptr<Class1> make();
};
Файл demo.cpp
// demo.cpp
#include "demo.hpp"
class Class2 {
public:
int value() const { return 0; }
};
Class1::Class1() {}
Class1::~Class1() {}
std::unique_ptr<Class1> Class1::make() { return std::make_unique<Class1>(); }
Файл main.cpp
#include "demo.hpp"
int main() {
auto c = Class1::make();
}
Компилировал под Ubuntu 22.04 так:
clang++-16 -o demo -std=c++17 main.cpp demo.cpp
Поскольку clang работает поверх стандартной библиотеки от GCC, то диагностика при переносе конструктора в .hpp-файл такая:
In file included from main.cpp:1:
./demo.hpp:10:5: error: variable has incomplete type 'Class2'
C v;
^
./demo.hpp:14:10: note: in instantiation of function template specialization 'Class1::get_v<Class2>' requested here
int v_{ get_v<Class2>() };
^
./demo.hpp:5:7: note: forward declaration of 'Class2'
class Class2;
^
1 error generated.
Возможно, если будет родная stdlib от clang-а (как на MacOS), то и диагностика будет другой. Но я сильно сомневаюсь. Так что, предположу, грабли у ТС-а все-таки другие.