你可以做injected
成static int
代替:
template<int A>
struct MagicStruct
{
enum { current = A };
static int injected;
};
template<int A>
int MagicStruct<A>::injected;
然後給InjectionStruct
靜態成員,其實例將在MagicStruct<A>::injected
填寫:
template<int A, int B>
struct InjectionStruct : MagicStruct<A>
{
enum { first=A, second=B};
struct filler {
filler() { MagicStruct<A>::injected = B; }
};
static filler inject;
};
template <int A, int B>
typename InjectionStruct<A,B>::filler InjectionStruct<A,B>::inject;
然後進行注射,你只需要在某處使用inject
,或者明確地實例化它:
static const int AVALUE = 1;
static const int BVALUE = 2;
static const int CVALUE = InjectionStruct<AVALUE, BVALUE>::first; //== 1
static const int DVALUE = InjectionStruct<AVALUE, BVALUE>::second; //== 2
//explicit instantiation
template InjectionStruct<AVALUE,BVALUE>::filler
InjectionStruct<AVALUE,BVALUE>::inject;
static const int EVALUE = MagicStruct<AVALUE>::injected; //== 2
或者,你可以隱藏在injected
您使用檢索first
或second
一些功能的實例。
這是一個瘋狂的實現,它依賴於通過模板實例化注入函數的實現。這可能不是你的編譯器的工作,如果它不執行有關標準正確的規則,但它是有趣儘管如此,在編譯時完全透明的工作原理:
template<typename>struct Type{};
template<int A>
struct MagicStruct
{
friend constexpr int get_injected(Type<MagicStruct<A>>);
static constexpr int current() { return A; }
template <int V = get_injected(Type<MagicStruct<A>>{})>
static constexpr int injected() { return V; }
};
template<int A, int B>
struct InjectionStruct
{
static constexpr int first() { return A; }
static constexpr int second() { return B; }
friend constexpr int get_injected(Type<MagicStruct<A>>) { return B; }
};
你這個實現使用幾乎完全一樣,你想:
static const int AVALUE = 1;
static const int BVALUE = 2;
static const int CVALUE = InjectionStruct<AVALUE, BVALUE>::first(); //== 1
static const int DVALUE = InjectionStruct<AVALUE, BVALUE>::second(); //== 2
static const int EVALUE = MagicStruct<AVALUE>::injected(); //== 2
Live demo
關於你的[編輯]:如果你有20'InjectionStruct',哪一個是定義你的''MagicStruct'值injected'?正如我在答案中所解釋的那樣,您需要在'MagicStruct'和'InjectionStruct'提供數據之間建立關係。 –
好點e複雜的問題:)它沒有太多的道理我知道..但我認爲它應該採取一個評估/宣佈/定義/無論作爲最後.. – user3770392