[英]C++ Circular #include where forward declaration is not fix
我知道如何用兩個類來解決基本的循環依賴示例,其中每個類都需要知道另一個。
但是,我現在處在這種情況下,示例更加復雜,而前向聲明不是可以解決該問題的東西。
考慮這三個文件
// my_thread.hpp
template<typename Function> class my_thread;
template<typename Return, typename... Input>
struct my_thread<Return(Input...)>
{
void somefunction() { thread_manager::static_function(); }
}
// thread_manager.hpp
struct thread_manager
{
static void static_function() { }
std::list<some_class::thread_type> threads;
}
// some_class.hpp
struct some_class
{
using thread_type = my_thread<int(some_class*)>
}
現在,顯然my_thread.hpp
需要整個thread_manager
(或者至少是它的功能?)。 thread_manager
需要using
從指令some_class
和some_class
取決於my_thread
。 由於STL容器需要完整的類型模板參數,因此無法轉發聲明my_thread
。 我什至無法給出my_thread<T>::somefunction()
,因為它是模板函數,需要放在標頭中。
我的問題是,如何解決這種循環依賴關系?
有趣的是, for some reason. I don't know how it knows about
,MSVC不需要#include "thread_manager" in
my_thread.hpp #include "thread_manager" in
包含#include "thread_manager" in
for some reason. I don't know how it knows about
for some reason. I don't know how it knows about
thread_manager`的for some reason. I don't know how it knows about
。
解決此問題的一種方法是將線程管理器作為模板參數注入:
// my_thread.hpp
template<typename ThreadManager, typename Function> class my_thread;
template<typename ThreadManager, typename Return, typename... Input>
struct my_thread<ThreadManager, Return(Input...)>
{
void somefunction() { ThreadManager::static_function(); }
}
您的some_class
必須傳遞線程管理器,但它對線程管理器一無所知,因此您也必須將線程管理器注入some_class
:
// some_class.hpp
template<typename ThreadManager>
struct some_class
{
using thread_type = my_thread<ThreadManager, int(some_class*)>;
};
最后,線程管理器可以將自身注入some_class
:
// thread_manager.hpp
struct thread_manager
{
static void static_function() { }
std::list<my_thread<thread_manager, int(int)>> threads;
}
通過這種結構,不再直接依賴線程管理器。
some_class
,您可能希望在某些單線程上下文中使用some_class
。 在這種情況下,您可以創建一個虛擬ThreadManager
,它提供與thread_manager
相同的接口,但是不執行任何操作,並將此類設置為默認模板參數。
#include <list>
// my_thread.hpp
template<typename Function> class my_thread;
// thread_manager.hpp
struct thread_manager
{
static void static_function() { }
std::list<my_thread<int(int)>> threads;
} ;
template<typename Return, typename... Input>
struct my_thread<Return(Input...)>
{
void somefunction() { thread_manager::static_function(); }
} ;
另一個變體:將某些功能的聲明保留在模板中,並在單獨的文件中實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.