C ++:在vector< int>中调用了哪些构造函数vn {MyAllocator< int>(a)}? [英] C++: which constructors are called in vector<int> vn{MyAllocator<int>(a)}?

查看:106
本文介绍了C ++:在vector< int>中调用了哪些构造函数vn {MyAllocator< int>(a)}?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个琐碎的分配器:

I have a trivial allocator:

// alloc.h
#include <cstdlib>
#include <new>
#include <iostream>

template <class T>
struct Mallocator {
  typedef T value_type;
  Mallocator() {
        std::cout << "default ctor is called" << std::endl;
  }
  template <class U> Mallocator(const Mallocator<U>&) {
        std::cout << "copy ctor is called" << std::endl;
  }
  T* allocate(std::size_t n) {
    std::cout << "Mallocator::allocate(size_t n) is called, n = " << n << " ";
    if(n > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
    if(T *p = static_cast<T*>(std::malloc(n*sizeof(T)))) {
        std::cout << "return p = " << std::hex << (uintptr_t)p << std::dec << std::endl;
        return p;
    }
    throw std::bad_alloc();
  }
  void deallocate(T* p, std::size_t n) { 
      std::cout << "Mallocator::deallocate(T *p, size_t n) is called, p = " << std::hex << (uintptr_t)p << std::dec << " n = " << n << std::endl;
      std::free(p);
  }
};
template <class T, class U>
bool operator==(const Mallocator<T>&, const Mallocator<U>&) { return true; }
template <class T, class U>
bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { return false; }

这是客户端代码(仅 A B C ):

And this is the client code (only one of A, B, C is used):

#include "alloc.h"
#include <vector>
#include <iostream>
using namespace std;

int main() {
    Mallocator<int> a;
    cout << "---instantiate---" << endl;
    // vector<int, Mallocator<int>> v(a);                  // A
    vector<int, Mallocator<int>> v{Mallocator<int>(a)};    // B
    // vector<int, Mallocator<int>> v(Mallocator<int>(a)); // C
    cout << "---push_back(1)---" << endl;
    v.push_back(1);
    cout << "---push_back(2)---" << endl;
    v.push_back(2);
    cout << "---push_back(3)---" << endl;
    v.push_back(3);
    cout << "---push_back(4)---" << endl;
    v.push_back(4);
    cout << "---push_back(5)---" << endl;
    v.push_back(5);
    cout << "---exiting---" << endl;
}

输出,无论 A B ,总是这样:

The output, no matter A or B is used, is always this:

default ctor is called
---instantiate---
---push_back(1)---
// omitted for brevity..

我的问题

(1)如果 A 存在,分配器仅构造一次,这是可以理解的。但是,当使用 B 而不是 A 时,显然是 Mallocator B 中被调用,但是输出不反映这一点。为什么?

(1) if A is present, the allocator is just constructed once, that's understandable. But when B is present instead of A, apparently the copy constructor of Mallocator is called in B, but the output doesn't reflect this. Why?

(2)如果存在 B ,则哪个 std构造函数:: vector 被称为?在此引用中,唯一需要初始化器列表的构造器没有看起来像这样。如果我使用 C 而不是 B ,它将无法编译,并且clang ++的错误消息也无济于事..

(2) If B is present, which constructor of std::vector is called? In this reference, the only constructor that takes an initializer list doesn't look like this. And if I use C instead of B, it won't compile, and the error message of clang++ is not helping..

Eidt:我知道这个分配器是微不足道的,但这不是这个问题的重点。

Eidt: I know this allocator is trivial but it is not the point of this question..

alloc.h的代码改编自此处

The code of "alloc.h" is adapted from here, at the end of the page.

推荐答案

1)您的副本构造函数不是一个。真正的副本构造函数不是模板。如果每个类都没有声明自己,则它会隐式声明一个副本构造函数。 Mallocator< int> 并未声明真正的副本构造函数,因此将为您隐式声明和定义。由于您的类为空,因此复制构造函数不执行任何操作,也不打印任何内容(并且由于重载解析规则,已选择复制构造函数模板上的分配器)。

1) Your "copy constructor" isn't one. A real copy constructor isn't a template. Every class gets a copy constructor implicitly declared if it doesn't declare one itself. Mallocator<int> doesn't declare a real copy constructor, so one gets implicitly declared and defined for you. Since your class is empty, that copy constructor does nothing and prints nothing (and, thanks to the overload resolution rules, is selected to copy the allocator over your constructor template).

2)如果没有可用的初始化器列表构造器,则列表初始化可以调用非初始化器列表构造器。 B 最终调用与 A 相同的构造函数。您的 C

2) List-initialization can call non-initializer-list constructors if no initializer-list constructor is viable. B ends up calling the same constructor as A. Your C is a case of the most-vexing-parse.

这篇关于C ++:在vector&lt; int&gt;中调用了哪些构造函数vn {MyAllocator&lt; int&gt;(a)}?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆