template < parameter-list > declaration
参数列表中的每个参数可以是:
几分钟前,我找到了
template<typename>/*(a type template parameter)*/
template<int>/*a non-type template parameter*/
是合法的。
所以,语法就像:
这是一个例子
template <typename T>
class ArrayList
{
std::vector<T> vec;
public:
template<class> // Mark!
class Ref {
ArrayList<T> *array;
int position;
public:
Ref(ArrayList<T> *a, int pos):array(a), position(pos) {};
Ref<T> &operator=(T v) {
if (array->vec.size() <= position)
array->vec.resize(position+1);
array->vec[position] = v;
}
operator T() const {
if (array->vec.size() <= position)
throw std::exception();
return array->vec[position];
}
};
Ref<T> operator[](int p) {return Ref<T>(this, p); };
};
我在函数的参数type fun(type) {}
中知道类似的习惯用法,唯一的用法是我们不需要name
,type
就足够了。
我的问题是:
Ref
的实施中,template<class>
代替template<class T>
或template<class U>
有什么好处。我想这是因为我们这里不需要额外的T/U
(确切地说,它是U
,因为额外的T
会导致阴影错误)template <typename T> class ArrayList
name
中排除多余的parameter-list
。我希望看到更多的应用程序。 答案 0 :(得分:1)
在您的特定示例中,没有任何好处。它没有充分理由使Ref
成为会员模板。
如果我们将模板视为元函数,那么如果可以调用它,则与函数参数相同。我们可以发信号通知该参数被忽略,并且不会影响所产生的特化。您可以在标签调度代码中看到它。例如:
template<typename> struct tag{};
template<typename T>
void do_foo_for(tag<T>) = delete;
void do_foo_for(tag<int>) {
// Do stuff
}
void do_foo_for(tag<std::string>) {
// Do stuff
}
template<typename T>
void foo() {
do_foo_for(tag<T>{});
}
在上面,我们使用tag
模板创建一个廉价类型来执行重载解析。当我们希望模板函数的实现根据类型参数做不同时,通常会这样做。由于重载通常比函数模板特化更强大,因此我们会根据tag
模板生成的不同类型进行重载。这种类型对于各种重载很重要,但对于模板本身而言,类型的名称并不重要,因此我们不打算命名它。
标签发送的用途太宽泛,无法在此描述,因此以上是一个玩具示例。但它演示了如何在&#34;类型&#34;上发送函数。
答案 1 :(得分:1)
除了注入类,我们何时会在参数列表中排除冗余名称。我希望看到更多的应用程序。
另一个使用示例是使用class
/ struct
模板专业化。
假设您要编写自定义类型特征,以了解某个类型是否为某个类型的std::vector
。
您可以按如下方式编写
template <typename>
struct isVect : public std::false_type
{ };
template <typename ... Ts>
struct isVect<std::vector<Ts...>> : public std::true_type
{ };
因此默认值为“不是矢量”,但当类型为std::vector<Ts...>
时,变为“是矢量”。
注意您需要接收类型,但只有在您需要了解它的专业化中才会知道。
您可以编写说明模板类型
标识符的通用版本// ................V you can add a type identifier, but why?
template <typename T>
struct isVect : public std::false_type
{ };
但是你没有使用它,所以为什么要明确这个名字?