[英]Template Aliases - question (tour of c++)
我正在瀏覽 C++ 之旅中的模板別名。 我無法理解下面的代碼以及如何使用它?
template<typename T>
class Vector {
public:
using value_type = T;
}
這里他使用 value_type 作為 typename 'T' 的類型別名,為什么我們不能只使用 typename T,因為我們可以將任何類型傳遞給模板(即 class 向量)。 模板需要別名是什么?
template<typename C>
using Value_type = typename C::value_type;
這里 C 的 scope 中的 value_type 是怎樣的,即我們如何使用類型“C”引用 value_type,因為它在 class“向量”內? 'value_type' 這里是指它的向量嗎? 和“Value_type”的意思是 int::Vector 或 string::Vector 等..?
template<typename Container>
void algo(Container &c)
{
Vector<Value_type<Container>> vec;
}
這三個部分是如何聯系起來的?
為什么是會員別名?
考慮您在其他一些通用代碼中使用Vector
的實例化:
template <typename U>
void foo(const U& u);
Vector<int> v;
foo(v);
然后在foo
內部,我們需要通過一些箍來 go 找出T
是int
。 foo
只知道U
是Vector<int>
。 如果Vector<int>
有一個value_type
別名,那么訪問它要簡單得多:
template <typename U>
void foo(const U& u) {
using value_type = typename U::value_type;
//...
}
現在foo
不需要關心U::value_type
實際上是Vector
的T
參數,並且對於不是模板實例化的類型也可以:
struct OtherVector {
using value_type = int;
};
OtherVector ov;
foo(ov);
沒有會員別名:“some hoops”
使用成員別名是一種簡單的方法。 為了完整起見,我想展示讓foo
從Vector<T>
推斷T
的復雜方法。 你得忍受我...
首先,請注意 function 模板不能部分特化。 這就是為什么我引入一個間接級別:
template <typename U>
struct foo_impl {
void operator()(const U& u) {
std::cout << "Hello \n";
}
};
template <typename U>
void foo(const U& u) { foo_impl<U>{}(u); }
調用者將調用foo
並且在后台我們可以使用foo_impl
。 例如,我們可以為Vector<T>
添加部分規范,我們可以直接訪問T
:
template <typename T>
struct foo_impl< Vector<T> > {
void operator()(const Vector<T>& v) {
std::cout << "Hello Vector<T>\n";
if constexpr (std::is_same_v<int,T>) {
std::cout << "T == int\n";
}
}
};
但是,請考慮這對foo
意味着什么。 上面的foo
適用於任何具有value_type
別名的類型。 現在我們有了一個相當無聊的通用定義(打印"Hello"
)和Vector<T>
的特化(當T==int
時打印更多)。 如果我們希望foo
也可以使用
template <typename T>
struct Bar {};
我們能做什么? 我們可以提供一個更通用的特化來匹配Bar
的實例化:
template <template<class> class A, class T>
struct foo_impl< A<T> > {
void operator()(const A<T>& v) {
std::cout << "Hello A<T>\n";
if constexpr (std::is_same_v<int,T>) {
std::cout << "T == int\n"; // We know what T is when a Vector<T> is passed !!
}
}
};
它使用模板模板參數來匹配模板的任何實例化與單個模板參數。
我們現在好嗎? 不幸的是,沒有,因為假設我們想從中獲得一個“值類型”:
template <typename A,typename B>
struct Moo {};
假設按照慣例,第一個參數A
是我們正在尋找的值類型。 然后我們需要添加一個更通用的特化:
template <template<class...> class A, typename T,typename... Others>
struct foo_impl< A<T,Others...> > {
void operator()(const A<T,Others...>& v) {
std::cout << "Hello A<T>\n";
if constexpr (std::is_same_v<int,T>) {
std::cout << "T == int\n";
}
}
};
這將匹配具有任意數量類型參數的模板實例化,並將檢測到第一個模板參數為T
。
我們還好嗎? 不幸的是:一點也不。 以上不符合
template <typename A, int x>
struct Omg {};
因為它有一個非類型模板參數。 我們也可以解決這個問題,但讓我們停在這里。 無論如何,要求值類型始終是第一個參數過於嚴格。
TL;博士
我們真正想要的是讓foo
與任何具有關聯“值類型”的類型一起工作。 做到這一點的簡單方法是任何應該傳遞給foo
以提供名為value_type
的成員別名的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.