相关疑难解决方法(0)

将const std :: string&作为参数传递的日子是多少?

我听取了香草萨特最近的谈话谁建议的理由来传递std::vectorstd::string利用const &在很大程度上消失了.他建议现在更好地编写如下函数:

std::string do_something ( std::string inval )
{
   std::string return_val;
   // ... do stuff ...
   return return_val;
}
Run Code Online (Sandbox Code Playgroud)

我理解return_val在函数返回时将是一个rvalue,因此可以使用非常便宜的移动语义返回.但是,inval仍然远大于引用的大小(通常实现为指针).这是因为a std::string具有各种组件,包括指向堆的指针和char[]用于短字符串优化的成员.所以在我看来,通过引用传递仍然是一个好主意.

谁能解释为什么Herb可能会说这个?

c++ c++11

579
推荐指数
11
解决办法
17万
查看次数

如何正确传递参数?

我是C++初学者,但不是编程初学者.我正在努力学习C++(c ++ 11),对我来说,最重要的是有点不清楚:传递参数.

我考虑过这些简单的例子:

  • 一个包含其所有成员基本类型的类:
    CreditCard(std::string number, int expMonth, int expYear,int pin):number(number), expMonth(expMonth), expYear(expYear), pin(pin)

  • 具有成员基本类型+ 1复杂类型的类:
    Account(std::string number, float amount, CreditCard creditCard) : number(number), amount(amount), creditCard(creditCard)

  • 具有成员基本类型的类+具有某种复杂类型的1个集合: Client(std::string firstName, std::string lastName, std::vector<Account> accounts):firstName(firstName), lastName(lastName), accounts(accounts)

当我创建一个帐户时,我这样做:

    CreditCard cc("12345",2,2015,1001);
    Account acc("asdasd",345, cc);
Run Code Online (Sandbox Code Playgroud)

显然,在这种情况下,信用卡将被复制两次.如果我重写该构造函数为

Account(std::string number, float amount, CreditCard& creditCard) 
    : number(number)
    , amount(amount)
    , creditCard(creditCard)
Run Code Online (Sandbox Code Playgroud)

会有一份副本.如果我把它重写为

Account(std::string number, float amount, CreditCard&& creditCard) 
    : number(number)
    , amount(amount)
    , creditCard(std::forward<CreditCard>(creditCard))
Run Code Online (Sandbox Code Playgroud)

将有2个动作,没有副本.

我想有时您可能想要复制一些参数,有时您不希望在创建该对象时进行复制.
我来自C#,用于引用,对我来说有点奇怪,我认为每个参数应该有2个重载,但我知道我错了.
有没有关于如何在C++中发送参数的最佳实践,因为我真的发现它,比方说,并非琐碎.你会如何处理我上面提到的例子?

c++ c++11

105
推荐指数
3
解决办法
8461
查看次数

我应该使用rvalues为std :: string编写构造函数吗?

我有一个简单的课程:

class X
{
    std::string S;
    X (const std::string& s) : S(s) { }
};
Run Code Online (Sandbox Code Playgroud)

我最近读过一些关于rvalues的内容,我一直在想,如果我应该编写X使用rvalue的构造函数,那么我能够检测出std::string类型的临时对象吗?

我认为应该看起来像:

X (std::string&& s) : S(s) { }
Run Code Online (Sandbox Code Playgroud)

据我所知,在支持C++ 11的编译器中实现std :: string应该在可用时使用它的移动构造函数.

c++ string constructor rvalue-reference c++11

14
推荐指数
4
解决办法
3969
查看次数

std :: move在类模板中的构造函数初始化列表中

我有这样的模板:

template<typename T>
struct foo {
  T m_t;
  foo(T t) : m_t(t) {}
};
Run Code Online (Sandbox Code Playgroud)

问题是我想支持小/常规类型和巨大类型(如矩阵)T.您是否建议我像这样编写构造函数初始化列表

foo (T t) : m_t(std::move(t)) {}
Run Code Online (Sandbox Code Playgroud)

并要求类型T始终支持移动构造,即使是较小的类型?还有更好的方法吗?

c++ move-semantics c++11

10
推荐指数
2
解决办法
3244
查看次数

在构造函数初始化列表上移动shared_ptr

最近我看到了几个这样的代码示例,其中std :: move用于构造函数初始化列表(不是移动构造函数).

class A {
public:
    A(std::shared_ptr<Res> res) : myRes(std::move(res)) {
    // ...
    }

private:
    std::shared_ptr<Res> myRes;
}
Run Code Online (Sandbox Code Playgroud)

我得到的信息是这个结构是出于优化原因.我个人使用std :: move尽可能少见.我威胁他们作为演员(如Scott Meyers所说),并且只在调用者代码中(只有例外是移动构造函数).对我来说,它看起来像某种混淆或微观优化,但也许我错了.是不是真的,如果没有std :: move,编译器不会产生更快的代码?

c++ optimization move move-semantics c++11

5
推荐指数
1
解决办法
914
查看次数

C++ 11:按值调用,移动语义和继承

假设我有一个类,我打算将它作为可实例化的类直接暴露给程序员:

class Base
{
public:
    Base(std::string text) : m_text(std::move(text)) {}
private:
    std::string m_text;
};
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.这里不需要rvalue构造函数.现在,在未来的某个时刻,我决定扩展Base:

class Derived : public Base
{
public:
    Derived(const std::string &text) : Base(text) {}
};
Run Code Online (Sandbox Code Playgroud)

这让我感到困惑:我无法在Derived中按值获取字符串,因为这就是Base已经在做的事情 - 我最终会得到2个副本和1个移动.这里的const-reference构造函数还对rvalues执行不必要的复制.

问题是:如何复制+仅移动一次(就像Base中的简单构造函数一样)而不添加更多构造函数?

c++ inheritance move move-semantics c++11

4
推荐指数
1
解决办法
1652
查看次数