std :: set构造函数签名混乱

时间:2018-07-05 05:03:00

标签: c++

我正在阅读有关如何定义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:

  1. 教科书以set为例,但是multisetconst Allocator& alloc = Allocator()的“签名”非常相似。
  2. 我不知道{{1}}是什么意思,但是我认为这是自动完成的事情吗?我现在可能会忽略它。

2 个答案:

答案 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*&)

在本书的示例中,Comparedecltype(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 作为模板的参数。所述类型必须是函数指针的类型。

  

第二个参数应该是一个类吗?

第二个参数必须是类型。模板类型参数由两个关键字之一classtypename指定。但是它们含义相同,您提供的参数必须是类型。

  

构造函数是否不需要函数引用?

否,它需要引用您作为参数给出的类型的对象。由于您将函数指针指定为类型,因此需要引用函数指针。那就是最终收到的东西。