我正在阅读有关如何定义set
的 C ++ Primer 。当我浏览有关set
的 cppreference 时,我对bool compareIsbn(){....}
multiset<Sales_data, decltype(compareIsbn) *> bookstore(compareIsbn)
的类和构造函数签名感到困惑。
摘自文本:
Sales_data
文本1:
要使用我们自己的操作,我们必须使用两种类型定义多重集: 键类型
compareIsbn
和比较类型(函数) 可以指向compareIsbn
的指针类型。当我们定义对象 这种类型,我们提供一个指向我们打算使用的操作的指针。在 在这种情况下,我们提供了指向set<Class A, a function pointer>
的指针:
因此,从text1看来,我需要在template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;
中放置一个函数指针。
但是当我查找cppreference时,“签名”(不确定是否是正确的单词)是:
class
问题1 :第二个参数应该是compareIsbn
吗?
文本2:
我们可以写
&compareIsbn
代替&compareIsbn
作为构造函数 参数,因为当我们使用函数名称时,它是 必要时自动转换为指针。我们可以有 书面set(); explicit set( const Compare& comp, const Allocator& alloc = Allocator() );
具有相同的效果。
也来自cppreference constructor of set(我认为教科书正在使用第一个构造函数):
multiset
问题2 :构造函数是否不需要函数引用?从哪里说它需要一个功能指针?
需要一些帮助来了解“签名”,在此先感谢:D。
PS:
set
为例,但是multiset
和const Allocator& alloc = Allocator()
的“签名”非常相似。答案 0 :(得分:3)
这有点令人困惑,但相当接近正确。
用'class'指定的类型模板参数是一个历史/语法上的怪癖;实际上表明参数是一种类型。 'typename'也是合法的,并且在语义上是相同的:
template<typename T>
struct Foo {
T thing;
}
template<class T>
struct Bar {
T thing;
}
// Foo and Bar will work identically
在本书的示例中,传递给模板的类型是“指向CompareIsbn的类型的指针”
关于第二个问题,请记住Compare
是一种类型:
template<typename T>
void Foo(const T& object) { ... }
模板函数Foo希望传递一个对T的const引用。如果T是指针类型,则它希望对一个指针的const引用:
Thing* bar = new Thing();
Foo<Thing*>(bar); // This instantiation of the template has signature void (const Thing*&)
在本书的示例中,Compare
是decltype(CompareIsbn)*
,因此必须将const decltype(CompareIsbn)*&
传递给构造函数。
cppreference有一个page,详细说明了Compare
模板中用于set
参数的类型的要求,您可能会发现这很有用。简短的版本是它必须是可以使此代码起作用的类型:
// Given Compare comp
// Given Key a, b
bool b = comp(a, b);
然后有一些关于如何调用operator()
的要求。
函数指针将在该上下文中工作,所以很好。但是std::function
或任何以正确行为实现operator()
的类型也将如此。模板声明中的= std::less<Key>
位将Compare
参数的默认值设置为这样的对象,它仅尝试使用Key::operator<
。
Allocator
参数也是一个类似于函数的对象,用于在必要时创建新的Key
对象。您很少需要提供显式分配器。默认实现几乎可以在所有情况下正常工作。
答案 1 :(得分:1)
因此,从text1看来,我需要在
中放置一个函数指针。set<Class A, a function pointer>
不完全是。是的,您需要提供一个指向构造函数的函数指针,但是文本告诉您您需要提供一个 type 作为模板的参数。所述类型必须是函数指针的类型。
第二个参数应该是一个类吗?
第二个参数必须是类型。模板类型参数由两个关键字之一class
或typename
指定。但是它们含义相同,您提供的参数必须是类型。
构造函数是否不需要函数引用?
否,它需要引用您作为参数给出的类型的对象。由于您将函数指针指定为类型,因此需要引用函数指针。那就是最终收到的东西。