[英]Initialize nested template classes
我有許多模板類,它們以任意順序一起工作(共享相同的概念)。
假設我有:
template<typename T>
class A {
T t_;
public:
void call() {
// Do something.
t_.call();
}
};
template<typename T, typename U>
class B {
T t_;
U u_;
public:
void call() {
// Do something.
t_.call();
// Do something.
u_.call();
}
};
class C {
public:
void call() {
// Do something.
}
};
我有以下實例化的類:
using Foo = A<B<A<C>,C>>;
讓我們假設,C可能需要一個特殊的構造函數(或初始化函數)。 我只在運行時才知道的東西。
struct C {
void init(int);
void call();
};
我如何初始化Foo? 還是任何其他嵌套類組合?
我當前的解決方法是將C定義為:
template<typename I>
struct C {
C() : var_(I::get())
void call();
};
並在函數內部創建Foo:
int main()
{
int i = 0;
struct HelperC1 {
static int get(bool set = false, int value = 0) {
static int value_ = value;
if (set) value_ = value;
return value_;
}
} helperC1;
struct HelperC2 {
static int get(bool set = false, int value = 0) {
static int value_ = value;
if (set) value_ = value;
return value_;
}
} helperC2;
helperC1.get(true, i);
helperC2.get(true, i+1);
A<B<A<C<HelperC1>>,C<HelperC2>>> foo;
foo.call();
return 0;
}
您會發現,此解決方法不是很方便。 另一種方法是使用參數調用Foo的第一個構造函數,並將它們重定向到C,但這對於不同的類組合(例如:
using Bar = A<B<A<C>,<B<B<A,C>,C>>>;
問題:如何使用運行時參數(更好/更簡潔的方式)初始化嵌套(模板)類?
您可以使用指針,並使用已構造和初始化的對象來構造foo
。 即:
未測試的代碼
template<typename T>
class A {
T* t_;
public:
A(T* valptr) : t_(valptr){}
~A(){ delete t_ ; }
void call() {
// Do something.
t_.call();
}
};
template<typename T, typename U>
class B {
T* t_;
U* u_;
public:
B(T* val1ptr, U* val2ptr):t_(val1ptr), u_(val2ptr){}
~B(){delete val1ptr; delete val2ptr;}
void call() {
// Do something.
t_->call();
// Do something.
u_->call();
}
};
class C {
private:
int x_;
public:
C(int x):x_(x){}
void call() {
// Do something.
}
};
用法:
A<B<A<C>,C>> foo( new B<A<C>,C>(new A<C>(new C(3) ), new C(3) ) );
本示例使用移動構造和轉發幫助器功能為分支模板類型構建值。
轉發助手使用類型推斷來包裝構造函數,以避免需要為每個構造函數指定復雜的參數。
在此示例中,call()函數轉儲對象的子代的參數結構和值。
#include <iostream>
#include <utility>
template<typename T>
class A {
T t;
public:
A(T&& t) : t{std::move(t)} {}
void call() {
std::cout << "A<";
t.call();
std::cout << ">";
}
};
template <typename T>
inline A<T> mkA(T&& t) { return A<T>{std::forward<T>(t)}; }
template<typename T, typename U>
class B {
T t;
U u;
public:
B(T&& t, U&& u) : t{std::move(t)}, u{std::move(u)} {}
void call() {
std::cout << "B<";
t.call();
std::cout << ",";
u.call();
std::cout << ">";
}
};
template <typename T, typename U>
inline B<T,U> mkB(T&& t, U&& u) {
return B<T,U>{std::forward<T>(t), std::forward<U>(u)};
}
class C {
int c;
public:
C(int c) : c{c} {}
void call() {
std::cout << "C(" << c << ")";
}
};
int main() {
auto bar = mkA(mkB(mkA(C{1}), mkB(mkB(mkA(C{2}),C{3}), C{4})));
bar.call();
std::cout << '\n';
}
輸出:
A<B<A<C(1)>,B<B<A<C(2)>,C(3)>,C(4)>>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.