Здравствуйте, Shmj, Вы писали:
S>А так возможно что попробовали и поняли что ваш вариант не работает, но признаваться стыдно и как бы хотите уйти в фактор личности.
Если ты уверен, что мой вариант не работает, почему бы тебе не согласиться на пари
? R>А ответ прост, на самом деле — протому что ты — ссылкивое трепло.
Мне предлагали менее жестокие условия — всего то не называть файлы словом test.h.
Не согласен, потому что вопрос касается теории и ответ нужен всем нам просто из любопытства и любознательности. Никакую реальную проблему этот ответ не решит, т.к. в проекте я просто перенес реализацию конструктора в CPP-файл.
Re[24]: Ошибка, если конструктор определен в h-файле (этюд?)
? R>>А ответ прост, на самом деле — протому что ты — ссылкивое трепло.
S>Мне предлагали менее жестокие условия — всего то не называть файлы словом test.h.
А какое значение для тебя имеет жесткость условий? Ты же УВЕРЕН, что мой вариант не работает? Уверен?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[25]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, Shmj, Вы писали:
S>Однако же в таком случае — вопрос бы получил ответ. Пока ответа полноценного нет.
Условие для полноценного ответа все еще в силе здесь
Здравствуйте, 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();
};
#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), то и диагностика будет другой. Но я сильно сомневаюсь. Так что, предположу, грабли у ТС-а все-таки другие.
Re[17]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, B0FEE664, Вы писали:
S>>Однако же в таком случае — вопрос бы получил ответ. Пока ответа полноценного нет. BFE>Условие для полноценного ответа все еще в силе здесь
Вы сейчас позорите честь форума и подтверждаете анекдот:
Американский форум- задал вопрос, тебе на него обстоятельно и вежливо ответят.
Еврейский форум- задал вопрос, тебе зададут встречный вопрос.
Русский форум-задал вопрос, тебе ещё 2 часа будут объяснять какой ты мудак!
Re[18]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, Shmj, Вы писали:
S>Вы сейчас позорите честь форума и подтверждаете анекдот:
S>
S>Американский форум- задал вопрос, тебе на него обстоятельно и вежливо ответят.
S>Еврейский форум- задал вопрос, тебе зададут встречный вопрос.
S>Русский форум-задал вопрос, тебе ещё 2 часа будут объяснять какой ты мудак!
Ну попробуйте задать свой вопрос на американском форуме. Делов-то.
Re[3]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, Shmj, Вы писали:
S>Вы сейчас позорите честь форума и подтверждаете анекдот:
Shmj, это не справедливо. Я вас нигде не оскорблял и не обижал.
Кстати, на американском форуме вопросы подобного рода (без всякого обсуждения) быстро закрывают с формулировкой вида "нет примера для воспроизведения проблемы".
И каждый день — без права на ошибку...
Re[8]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, Videoman, Вы писали:
V>Потому что дело не только в конструкторе, но и в деструкторе. std::unique_ptr<Class2> деструктор для неполного объекта также не может создать. С деструктором Class1 проделай тоже самое:
Вот зачем ты помогаешь этому персонажу?
Это как на дороге: длинная тянучка, и все дисциплинировано едут.
И тут кто-то "самый умный" обгоняет всех через сплошную (или по обочине, по вкусу) и пытается вклиниться в поток. И его обязательно кто-то впустит. И в следующий раз он сделает ровно так же.
И в понимании этого шумахера будет "все лохи и ездить не умеют, а я красавчик, сломал систему".
Вот так и этот придурок.
Не нужно таким помогать, они, в итоге, делают всем хуже (ну кроме себя, конечно).
S>Я все же думаю, что здесь ситуация несколько хитрее. S>Возможно, если будет родная stdlib от clang-а (как на MacOS), то и диагностика будет другой. Но я сильно сомневаюсь. Так что, предположу, грабли у ТС-а все-таки другие.
У меня описанные симптомы воспроизводятся в самом классическом варианте:
class Class1
{
public:
Class1();
~Class1();
private:
class Impl;
std::unique_ptr<Impl> m;
};
При переносе определения конструктора из cpp в тело класса получаю ошибку:
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\memory(3105,1): error C2027: use of undefined type 'Class1::Impl'
Visual Studio 2022 v17.6.4, toolset v143, /std:c++20
Вероятно, воспроизводимость чувствительна к компилятору и реализации STL.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[21]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, rg45, Вы писали:
R>У меня описанные симптомы воспроизводятся в самом классическом варианте:
Да, вы правы, на классическом PImpl получается ошибка, как раз с нужной диагностикой:
$ clang++-16 -o demo -std=c++17 main.cpp demo.cpp
In file included from main.cpp:1:
In file included from ./demo.hpp:3:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/memory:76:
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/unique_ptr.h:83:16: error: invalid application of 'sizeof' to an incomplete type 'Class1::Impl'
Вероятно, это я перемудрил
Но мне кажется, что Class1 по любому должен создаваться через какую-то фабрику, а не просто как значение на стеке (или в агрегате).
Re[22]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, so5team, Вы писали: S>Но мне кажется, что Class1 по любому должен создаваться через какую-то фабрику, а не просто как значение на стеке (или в агрегате).
Да и на стеке тоже должно воспроиводиться, почему нет. привожу ниже полный листинг моего варианта:
Class1.h
#pragma once
#include <memory>
class Class1
{
public:
Class1();
~Class1();
private:
class Impl;
std::unique_ptr<Impl> m;
};
Здравствуйте, rg45, Вы писали:
S>>Но мне кажется, что Class1 по любому должен создаваться через какую-то фабрику, а не просто как значение на стеке (или в агрегате).
R>Да и на стеке тоже должно воспроиводиться, почему нет. R>Это успешная версия. После переноса конструктора, появляется ошибка.
Потому что Shmj говорил, что изначально у Class1 вообще явно определенного конструктора не было, был только дефолтный, сгенерированный самим компилятором. Если я правильно понимаю, то вот в таком случае:
class Class2;
class Class1 {
std::unique_ptr<Class2> ptr_member_;
public:
// Нет ни конструктора, ни деструктора.
};
int main() {
Class1 c;
}
компиляция должна завершиться с ошибкой, т.к. здесь нет определения Class2.
Но вот в таком случае все OK:
class Class2;
class Class1 {
std::unique_ptr<Class2> ptr_member_;
public:
// Нет ни конструктора, ни деструктора.static std::unique_ptr<Class1> make();
};
int main() {
auto c = Class1::make();
}
Да и вообще класс с PImpl, у которого конструктор генерируется самим компилятором... Ну звучит как такое себе.
Re[19]: Ошибка, если конструктор определен в h-файле (этюд?)