gpt4 book ai didi

c++ - 模板别名-问题(C++之旅)

转载 作者:行者123 更新时间:2023-12-03 07:08:39 25 4
gpt4 key购买 nike

我正在浏览Tour C++中的Aliases模板。我不明白下面的代码以及如何使用它?

template<typename T>
class Vector {
public:
using value_type = T;
}
在这里,他使用value_type作为类型名“T”的类型别名,为什么我们不能仅使用类型名T,因为我们可以将任何类型传递给模板(即类Vector)。模板需要别名吗?
template<typename C>
using Value_type = typename C::value_type;
这里的value_type在C的范围内如何,即我们如何引用类型为'C'的value_type,因为它位于类“vector”中?
“value_type”在这里表示其 vector 吗?
和'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内部,我们将需要仔细研究一下以发现 Tintfoo只知道 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实际上是 TVector参数,并且对于不是模板实例化的类型也可以:
struct OtherVector {
using value_type = int;
};
OtherVector ov;
foo(ov);

没有成员别名:“箍”
使用成员别名是简单的方法。为了完整起见,我想展示让 fooT推断 Vector<T>的复杂方法。你要忍受我...
首先,请注意功能模板不能部分特化。因此,我引入了一个间接级别:
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";
}
}
};
Live Example
但是,请考虑这对 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 !!
}
}
};
Live Example
它使用模板临时参数来匹配具有单个模板参数的模板的任何实例。
现在好吗?不幸的是没有,因为假设我们要从中获取“值类型”:
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";
}
}
};
Live Example
这将使模板的实例化与任何数量的类型参数匹配,并将第一个模板参数检测为 T
我们还好吗?不幸的是:完全没有。
以上不符合
template <typename A, int x>
struct Omg {};
因为它具有非类型模板参数。我们也可以解决该问题,但让我们在这里停止。无论如何,要求值类型始终是第一个参数太严格了。
TL; DR
我们真正想要的是使 foo与任何具有关联“值类型”的类型一起使用。这样做的简单方法是,应将任何类型传递给 foo以提供成员别名 value_type

关于c++ - 模板别名-问题(C++之旅),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65053571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com