我有這樣的問題為什么模板只能在頭檔案中實作?(以及 使用模板類構建基于 CMake 的專案的正確方法)但包含遞回。
代碼:
啊
#pragma once
#include "B.h"
struct A
{
B b;
void doThingA() {}
};
溴化氫
#pragma once
struct A;
struct B
{
A *a;
template<typename T>
void doThingB();
};
#include "A.h"
template<typename T>
void B::doThingB()
{
a->doThingA();
}
主檔案
#include "A.h"
int main() {}
錯誤:
In file included from A.h:2,
from main.cpp:1:
B.h: In member function 'void B::doThingB()':
B.h:16:6: warning: invalid use of incomplete type 'struct A'
16 | a->doThingA();
| ^~
B.h:2:8: note: forward declaration of 'struct A'
2 | struct A;
| ^
B.h包含 fromA.h但A.h模板函式實作所需的B.h不包含。.cpp由于模板,我也無法實施。
可以通過使用模板的顯式實體化來解決,但我想知道另一種解決方案。
uj5u.com熱心網友回復:
當您擁有如此緊密耦合的型別時,最簡單的解決方案是將它們放在一個頭檔案中。
#pragma once
// forward declaration of A
struct A;
// declare B, since A needs it
struct B
{
A *a;
template<typename T>
void doThingB();
};
// now we can declare A
struct A
{
B b;
void doThingA() {}
};
// and finally, implement the parts of B that need A
// and need to be in the header
template<typename T>
void B::doThingB()
{
a->doThingA();
}
如果你仍然想要一個B.h,那么它可以是一行:
#include "A.h"
如果您想將A/拆分B為您自己的組織的多個標頭,一個簡單的解決方案是添加編譯時檢查以確保不直接包含檔案。
// A.h
#pragma once
#define A_IMPL
#include "B_impl.h"
#undef A_IMPL
// B.h
#pragma once
#ifndef A_IMPL
#error "B_impl.h can't be included directly; use A.h"
#endif
struct A;
struct B
{
A *a;
template<typename T>
void doThingB();
};
#include "A_impl.h"
template<typename T>
void B::doThingB()
{
a->doThingA();
}
// A_impl.h
#pragma once
#ifndef A_IMPL
#error "A_impl.h can't be included directly; use A.h"
#endif
struct A
{
B b;
void doThingA() {}
};
#ifdef如果您希望更多的標頭直接使用 impl 檔案,您可以使檢查更加復雜,但公共界面仍然很幸福地不知道。
uj5u.com熱心網友回復:
基于斯蒂芬的解決方案,我提出了該架構:
啊
#pragma once
#define A_H
#include "B.h"
struct A
{
B b;
void doThingA() {}
};
#include "B_impl.h"
溴化氫
#pragma once
struct A;
struct B
{
A *a;
template <typename T>
void doThingB();
};
#ifndef A_H
#include "B_impl.h"
#endif
B_impl.h
#pragma once
#include "A.h"
template <typename T>
void B::doThingB()
{
a->doThingA();
}
主檔案
#include "A.h"
int main() {}
所以我可以單獨包含A.h和B.h,而且它對我來說看起來更干凈。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/428000.html
