【问题标题】:Initializing std::string embedded in std::pair with non-1-argument ctor?使用非 1 参数 ctor 初始化嵌入在 std::pair 中的 std::string?
【发布时间】:2017-05-21 20:40:16
【问题描述】:

如果我想用一个带多个参数的构造函数构造嵌入式 std::string,是否可以构造一个 std::pair?

例如,这是合法的:

#include <iostream>
#include <utility>
#include <string>

int main()
{
  std::pair<int, int> pair(2, 3);
  return 0;
}

...这是合法的:

#include <iostream>
#include <utility>
#include <string>

int main()
{
  std::pair<int, std::string> pair(2, "hello");
  return 0;
}

...但我想知道是否可能出现以下情况:

#include <iostream>
#include <utility>
#include <string>

int main()
{
  std::pair<int, std::string> pair{2, {"hello", 3}}; //Unclear if some variation/combination of parentheses and curly braces can make this legal.
  return 0;
}

认为以上是使用“统一初始化列表”的正确语法,但这不适用于我的目的,因为我使用的是 C++11 之前的编译器。有没有办法用 C++11 之前的语法来解决这个问题?

为了澄清,我正在尝试使用这个 std::string 构造函数:

basic_string( const CharT* s,
              size_type count,
              const Allocator& alloc = Allocator() );

作为我问这个问题的背景,这是出于学术好奇心(如果错了,请纠正我):我认为像这样进行单行构造更有效,因为 std::pair 及其成员只是简单地创建和初始化一口气。而如果我做了这样的事情(使用 C++11 语法)......

#include <iostream>
#include <utility>
#include <string>

int main()
{
  std::pair<int, int> pair(2, 3);
  std::pair<int, std::string> pair2 = {2, {"hello", 3}};
  return 0;
}

...然后我在技术上创建一个std::pair&lt;int, std::string&gt;,其成员是默认构造的,然后调用std::pairoperator=,然后在该对的成员上调用operator=

【问题讨论】:

  • std::string("hello",3)?您尝试使用哪个构造函数,为什么?
  • @c650:更新帖子以回答您的问题。

标签: c++ string c++11 constructor std-pair


【解决方案1】:

只写:

std::pair<int, std::string> pair( 2, std::string( "hello", 3 ) ); 

至于这份声明:

std::pair<int, std::string> pair2 = {2, {"hello", 3}};

那么其实就等价于这个声明:

std::pair<int, std::string> pair{2, { "hello", 3}};

由于复制构造函数省略。考虑到没有赋值运算符,因为它是一个声明。

考虑以下示例:

#include <iostream>
#include <string>

int main()
{
    struct Pair
    {
        std::string s;
        int i;
        Pair(int i, const std::string &s) : i(i), s(s)
        {
            std::cout << "Pair( int, std::string )" << std::endl;
        }

        Pair( const Pair &p) : i(p.i), s(p.s)
        {
            std::cout << "Pair( const Pair & )" << std::endl;
        }
    };

    Pair p1{ 2, { "hello", 3 } };
    Pair p2 = { 2, { "hello", 3 } };
}

程序输出为:

Pair( int, std::string )
Pair( int, std::string )

【讨论】:

  • 我想这回答了我的问题,但我仍然很好奇:是否可以在不使用中间 std::string 对象的情况下使用 C++11 之前的语法?
  • @StoneThrow 不,这是不可能的。
  • 所以,Vlad,使用 C++11 语法,由于复制省略,构造 Pair 的两种方法效率相等,对吧? IE。我对默认构造后跟operator= 的多次调用的假设是不正确的,对吧?
  • @StoneThrow 没有赋值运算符。当使用其他对象创建对象时,就会使用构造函数:复制构造函数或移动构造函数。为了使复制省略有效,复制/移动构造函数必须是可访问的,尽管它没有被调用。
  • 第二种和第三种形式不等同“由于复制构造函数省略”。没有副本可以省略。 Copy-list-initialization 不会(甚至在名义上)创建一个临时的,不像它的非列表对应物。
猜你喜欢
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
  • 2010-11-16
  • 2018-01-13
  • 2020-03-26
  • 2016-02-04
  • 1970-01-01
  • 2023-02-23
相关资源
最近更新 更多