相关疑难解决方法(0)

C++ 11 rvalues和移动语义混淆(return语句)

我试图理解rvalue引用并移动C++ 11的语义.

这些示例之间有什么区别,哪些不会执行矢量复制?

第一个例子

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return tmp;
}

std::vector<int> &&rval_ref = return_vector();
Run Code Online (Sandbox Code Playgroud)

第二个例子

std::vector<int>&& return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp);
}

std::vector<int> &&rval_ref = return_vector();
Run Code Online (Sandbox Code Playgroud)

第三个例子

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp);
}

std::vector<int> &&rval_ref = return_vector();
Run Code Online (Sandbox Code Playgroud)

c++ c++-faq rvalue-reference move-semantics c++11

415
推荐指数
3
解决办法
10万
查看次数

使用成员函数启动线程

我试图std::thread用一个不带参数和返回的成员函数构造一个void.我无法弄清楚任何有效的语法 - 编译器无论如何都会抱怨.实现的正确方法是什么,spawn()以便返回std::thread执行的test()

#include <thread>
class blub {
  void test() {
  }
public:
  std::thread spawn() {
    return { test };
  }
};
Run Code Online (Sandbox Code Playgroud)

c++ multithreading c++11

269
推荐指数
4
解决办法
30万
查看次数

在C++中通过引用传递给参数的默认值

在我们通过引用传递参数时,是否可以为函数的参数提供默认值.在C++中

例如,当我尝试声明一个函数时:

virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
Run Code Online (Sandbox Code Playgroud)

当我这样做时,它给出了一个错误:

错误C2440:'default argument':无法从'const int'转换为'unsigned long&'不是'const'的引用不能绑定到非左值

c++ pass-by-reference default-value

113
推荐指数
7
解决办法
12万
查看次数

何时应该在函数返回值上使用std :: move?

在这种情况下

struct Foo {};
Foo meh() {
  return std::move(Foo());
}
Run Code Online (Sandbox Code Playgroud)

我很确定移动是不必要的,因为新创建的Foo将是一个xvalue.

但在这种情况下呢?

struct Foo {};
Foo meh() {
  Foo foo;
  //do something, but knowing that foo can safely be disposed of
  //but does the compiler necessarily know it?
  //we may have references/pointers to foo. how could the compiler know?
  return std::move(foo); //so here the move is needed, right?
}
Run Code Online (Sandbox Code Playgroud)

我认为需要采取行动吗?

c++ move-semantics c++11

109
推荐指数
4
解决办法
5万
查看次数

为什么从函数返回向量是可以的?

请考虑此代码.我已经多次看过这种类型的代码了.words是一个本地向量.如何从函数中返回它?我们可以保证它不会死吗?

 std::vector<std::string> read_file(const std::string& path)
 {
    std::ifstream file("E:\\names.txt");

    if (!file.is_open())
    {
        std::cerr << "Unable to open file" << "\n";
        std::exit(-1);
    }

    std::vector<string> words;//this vector will be returned
    std::string token;

    while (std::getline(file, token, ','))
    {
        words.push_back(token);
    }

    return words;
}
Run Code Online (Sandbox Code Playgroud)

c++ scope stl vector standard-library

106
推荐指数
4
解决办法
13万
查看次数

什么时候返回语句需要显式移动?

对另一个问题评论中, Jonathan Wakely回应了我的陈述:

您永远不需要显式移动局部变量函数返回值.这是隐含的举动

- >

...永远不要说永远......如果局部变量与返回类型的类型不同,则需要显式移动,例如std::unique_ptr<base> f() { auto p = std::make_unique<derived>(); p->foo(); return p; },但如果类型相同,则可能会移动...

所以有时我们可能不得不在返回时移动局部变量.

这个例子

std::unique_ptr<base> f() { 
  auto p = std::make_unique<derived>();
  p->foo(); 
  return p; 
}
Run Code Online (Sandbox Code Playgroud)

很好,因为它给出了编译错误

> prog.cpp:10:14: error: cannot convert ‘p’ from type
> ‘std::unique_ptr<derived>’ to type ‘std::unique_ptr<derived>&&’
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有一个很好的机会来检测这一般 - 这是这里的语言规则或unique_ptr ??

c++ return implicit-conversion move-semantics c++11

18
推荐指数
1
解决办法
1442
查看次数

C++ 11移动语义和右值引用

请考虑以下代码:

class StringTokenizer 
{
private:
    char m_delimiter;
    std::istringstream m_string;

public:
    explicit StringTokenizer(const std::string& str, char delimiter)
    : m_string(str)
    , m_delimiter(delimiter)
    {
    }

    template <class Container>
    operator Container ()
    {
        Container container;
        for (std::string token; std::getline(m_string, token, m_delimiter); )
        {
            container.insert(container.end(), token);
        }
        return container;
    }
};
Run Code Online (Sandbox Code Playgroud)

这是用法:

vector<string> tmp = StringTokenizer("123 456", ' '); //Please note the implicit conversion
Run Code Online (Sandbox Code Playgroud)

调试时发生以下情况(使用VS2013):

return转换运算符声明中

  1. container由移动构造的新向量
  2. container 被破坏了

功能返回后:

  1. tmp 由复制构造函数构造

我的问题是为什么不是tmp由移动构造函数构造的?

据我所知,函数返回类型是rvalue,应该移动.

c++ visual-c++ c++11 visual-studio-2013

8
推荐指数
1
解决办法
269
查看次数

存储指向NRVO返回的对象的指针

如果我编写一个在本地实例化对象然后按值返回的工厂方法,打算利用NRVO(根据这里的一些答案:c ++ 11返回值优化或移动?),指针/引用将是本地对象指向分配了方法返回值的对象?

Object ObjectBuilder::BuildObject( void )
{
    Object obj;

    //this->ObjectReference = obj; //Disregard this
    //OR
    this->ObjectPtr = &obj;

    return obj;
}
Run Code Online (Sandbox Code Playgroud)

正在使用:

ObjectBuilder builder;

Object newObject = builder.BuildObject();
Run Code Online (Sandbox Code Playgroud)

builder.ObjectPtr是否引用newObject?

c++ copy-elision c++11

8
推荐指数
1
解决办法
159
查看次数

移动返回对象的构造函数会破坏C ++ 98代码?

标准不需要编译器执行返回值优化(RVO),但是从C ++ 11开始,必须移动结果。

看来,这可能会将UB引入到/破坏代码中,这在C ++ 98中是有效的。

例如:

#include <vector>
#include <iostream>

typedef std::vector<int> Vec;
struct Manager{
    Vec& vec;
    Manager(Vec& vec_): vec(vec_){}
    ~Manager(){
        //vec[0]=42; for UB
        vec.at(0)=42;
    }
};

Vec create(){
    Vec a(1,21);
    Manager m(a);
    return a;
}

int main(){
    std::cout<<create().at(0)<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

当使用gcc(或与此相关的clang)进行编译时(为了简化示例,-O2 -fno-inline -fno-elide-constructors我正在使用std::vector这些build-option。如果没有这些选项以及手工类和更复杂的create功能,则可能会触发相同的行为)对于C ++ 98(-std=c++98)一切正常:

  1. return a;触发复制构造函数,它保持a原样。
  2. 的Destructor m称为(必须在a被销毁之前发生,因为它m是在之后构造的a)。a在析构函数中访问是没有问题的。
  3. 的析构a函数称为。

结果与预期的一样:21已打印(此处为live)。 …

c++ gcc rvo c++11

8
推荐指数
1
解决办法
328
查看次数

我可以在矢量上创建视图吗?

我有一个功能,需要对给定的元素进行排序。原始矢量一定不能更改,因此我需要该矢量的浅表副本。由于我不需要复制元素本身,因为它们只能被读取,所以我决定制作一个指针向量。目前,我有一个简单的循环来填充矢量,但是我想知道是否存在内置/标准解决方案,甚至可能更快。

void calcFindMinLeftAndSort(std::vector<Location>& locationsComplete, std::vector<Location*>& locationsSorted) {
    // ...

    // copy data in new array, to keep the original untouched
    locationsSorted.reserve(locationsComplete.size());
    // looking for locationsSorted.assign(&elements)
    // yes, I could use for each instead
    for (size_t i = 0; i < locationsComplete.size(); i++)
        locationsSorted.emplace_back(&locationsComplete[i]);

    // sort 
    std::sort(locationsSorted.begin(), locationsSorted.end(), compare);
}
Run Code Online (Sandbox Code Playgroud)

附加信息:locationsComplete向量按特定顺序排序,不得更改。该矢量在应用程序运行期间不会改变。排序后的locationSorted向量被另一个函数使用了一次(可以在同一函数中使用,但这种方式看起来更清晰)。返回下一个函数的结果后,locationsSorted向量将退役。因此,它可以看作是寿命很短的临时载体。

c++ vector c++11

7
推荐指数
1
解决办法
119
查看次数