小编Min*_*ine的帖子

如何使用删除的copy-ctor模拟方法返回对象?

如果一个接口有一个函数来创建一个删除了copy-ctor的对象,那么如何模拟这个函数呢?Gmock似乎在内部使用了对象的复制构造函数.

例如

// The object with deleted copy-ctor and copy-assignment
class TTest
{
public:
    TTest() = delete;
    TTest(const TTest&) = delete;
    TTest& operator=(const TTest&) = delete;
    TTest(TTest&&) = default;
    TTest& operator=(TTest&&) = default;

    explicit TTest(int) {
    }
};

// My interface to mock
class MyInterface
{
    public:
        virtual ~MyInterface() {}
        virtual TTest GetUniqueTest() = 0;
};

// The mock
class MockMyInterface: public MyInterface{
    public:
        MOCK_METHOD0(GetUniqueTest, TTest());
}
Run Code Online (Sandbox Code Playgroud)

编译错误说:

gmock/gmock-spec-builders.h:1330:20: error: use of deleted function 'TTest::TTest(const TTest&)'
     T retval(value_);
...
gmock/gmock-actions.h:190:52: …
Run Code Online (Sandbox Code Playgroud)

c++ unit-testing googletest gmock

9
推荐指数
2
解决办法
3670
查看次数

为什么std :: make_move_iterator适用于vector <string>,但不适用于vector <int>

我原以为这std::make_move_iterator总会移动内容,但似乎没有.

看起来它正在移动元素vector<string>而不是移动元素vector<int>.

请参阅以下代码段:

#include <iostream>
#include <iterator>
#include <string>
#include <vector>

void moveIntVector()
{
  std::cout << __func__ << std::endl;
  std::vector<int> v1;
  for (unsigned i = 0; i < 10; ++i) {
    v1.push_back(i);
  }
  std::vector<int> v2(
    std::make_move_iterator(v1.begin() + 5),
    std::make_move_iterator(v1.end()));
  std::cout << "v1 is: ";
  for (auto i : v1) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  std::cout << "v2 is: ";
  for (auto i : v2) {
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ string vector move-semantics c++11

8
推荐指数
2
解决办法
2852
查看次数

是否可以为constexpr函数定义类型别名

在C++ 11或C++ 14中,我试图为constexpr函数定义一个类型别名.

我试过了:

#include <iostream>
constexpr int foo(int i, int j) { return i + j; }
using TConstExprFunction  = constexpr int (*)(int i, int j);

int main() {
  TConstExprFunction f = foo;
  constexpr int i = f(1, 2);
  std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但它无法用g ++和clang ++编译.

克++: error: expected type-specifier before 'constexpr'

铛++: error: type name does not allow constexpr specifier to be specified

我必须按照以下方式进行编译

#include <iostream>
constexpr int foo(int i, int j) { return i + …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11 type-alias

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

使用移动成本低但要复制的对象初始化容器的首选方法是什么

考虑以下代码:

#include <iostream>
#include <vector>

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
  C(C&&) {std::cout << "A move was made.\n";}
};

std::vector<C> g() {
  std::vector<C> ret {C(), C(), C()};
  return ret;
}

std::vector<C> h() {
  std::vector<C> ret;
  ret.reserve(3);
  ret.push_back(C());
  ret.push_back(C());
  ret.push_back(C());
  return ret;
}

int main() {
  std::cout << "Test g\n";
  std::vector<C> v1 = g();

  std::cout << "Test h\n";
  std::vector<C> v2 = h();
}
Run Code Online (Sandbox Code Playgroud)

编译g++ -std=c++11 main.cpp && ./a.out,结果是:

Test g …
Run Code Online (Sandbox Code Playgroud)

c++ move initializer-list c++11

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

C ++ 11线程在互斥锁上挂起

使用C ++ 11 std::thread,std::mutex我正在编写一个简单的工作线程。但是,我在std::mutexlock中遇到了一个奇怪的挂起问题,它看起来好像两个线程(主线程和工作线程)都试图锁定互斥锁,但是都被阻塞了。

这是完整的代码

#include <thread>
#include <condition_variable>
#include <memory>
#include <iostream>
#include <list>
std::condition_variable cv;
std::mutex m;
std::thread t;
bool shouldExit = false;
std::list<int> jobs;

void thread_func()
{
  std::unique_lock<std::mutex> lock(m);
  while (!shouldExit) {
    while (jobs.empty() && !shouldExit) {
      cv.wait(lock);
    }
    // Do some stuff
    if (jobs.empty()) {
      continue;
    }
    // Get a job and do something with it
    if (!lock.owns_lock()) {
      lock.lock();  // <<<< Worker thread hang here
    }
    auto j = std::move(jobs.front()); …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading mutex locking c++11

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

在使用iterator和pop_back进行循环时出现奇异的迭代器错误

给出下面的代码(说它的名字deque.cpp)

#include <cstdio>
#include <deque>

int main()
{
  std::deque<int> d = {1, 2, 3};
  for (auto it = d.rbegin(); it != d.rend();) {
    printf("it: %d\n", *it);
    ++it;
    d.pop_back();
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译g++ -std=c++11 -o deque deque.cpp,运行良好:

$ ./deque
it: 3
it: 2
it: 1
Run Code Online (Sandbox Code Playgroud)

但如果编译为-D_GLIBCXX_DEBUG(g++ -std=c++11 -o deque_debug deque.cpp -D_GLIBCXX_DEBUG,它得到以下错误:

$ ./deque_debug
it: 3
/usr/include/c++/4.8/debug/safe_iterator.h:171:error: attempt to copy-
    construct an iterator from a singular iterator.
...
Run Code Online (Sandbox Code Playgroud)

看起来第二个循环++it是从一个奇异的迭代器构造的.但我想在第一个循环之后++it,迭代器指向2,并且 …

c++ iterator c++11 reverse-iterator

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

如果 p 以根路径开头,为什么 std::filesystem::path::append 替换当前路径

给出以下代码:

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    fs::path fsBase = "/base";
    fs::path fsAppend = "/append";
    auto fsResult = fsBase / fsAppend;

    std::cout << "fsResult: " << fsResult << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

通常,预期的结果是/base/append,但它实际上给出了/append。

fs::path::append的描述确实表明了这种行为:

如果 p.is_absolute() || (p.has_root_name() && p.root_name() != root_name()),然后用 p 替换当前路径,就像用 operator=(p) 并完成一样。

然而,行为std::experimental::filesystem和boost::filesystem不同的是,这给了预期/base/append。请参阅示例。

问题是为什么它会这样?为什么用append()函数替换路径?

c++ boost-filesystem c++17

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

是静态constexpr变量odr使用?

给出以下代码,是否使用Foo::FOO1ODR?

#include <iostream>
#include <map>
#include <string>

class Foo
{
public:
    static constexpr auto FOO1 = "foo1";
    void bar();
};

void Foo::bar()
{
    const std::map<std::string, int> m = {
        {FOO1, 1},
    };
    for (auto i : m)
    {
        std::cout << i.first << " " << i.second << std::endl;
    }
}

int main()
{
    Foo f;
    f.bar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用-O1或以上编译代码,没关系,但如果编译-O0,我得到以下错误(请参阅coliru示例:

undefined reference to `Foo::FOO1'
Run Code Online (Sandbox Code Playgroud)

表示它是ODR使用的.这是什么?


我知道上面的代码是用-O构建的,但是在一个真实的(更复杂的)情况下:

  • 代码编译并与-O2良好链接
  • 代码获取上述undefined reference …

c++ one-definition-rule c++14

3
推荐指数
1
解决办法
212
查看次数

如果删除不带虚拟dtor的类,为什么可以删除,如果它继承了带虚拟dtor的类

考虑下面的代码

#include <cstdio>
#include <memory>

struct Base1
{
    Base1() = default;
    virtual ~Base1() = default;
    //~Base1() = default;
};

struct Base2 : public Base1
{
    Base2()
    {
        printf("%s:%d:%s\n", __FILE__, __LINE__, __func__);
    }
    ~Base2() // non-virtual destructor
    {
        printf("%s:%d:%s\n", __FILE__, __LINE__, __func__);
    }
};

struct Derive : public Base2
{
    Derive()
    {
        printf("%s:%d:%s\n", __FILE__, __LINE__, __func__);
    }
    ~Derive()
    {
        printf("%s:%d:%s\n", __FILE__, __LINE__, __func__);
    }
};

int main()
{
    std::unique_ptr<Base2> d = std::make_unique<Derive>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该类Base2没有虚拟析构函数,但它继承Base1了具有虚拟析构函数的类。

代码 …

c++ virtual destructor

3
推荐指数
2
解决办法
75
查看次数

Dockerfile:如何根据ubuntu版本设置apt镜像

在构建 docker 镜像时,可以通过覆盖来设置自定义 apt 镜像/etc/apt/sources.list,例如

FROM ubuntu:focal

RUN echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal main restricted universe multiverse" > /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal-updates main restricted universe multiverse" >> /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal-security main restricted universe multiverse" >> /etc/apt/sources.list
...
Run Code Online (Sandbox Code Playgroud)

如果基础镜像是一个变量,例如FROM ${DISTRO},则应sources.list根据 ubuntu 版本进行调整。

我尝试$(lsb_release -cs)如下:

RUN echo "deb mirror://mirrors.ubuntu.com/mirrors.txt $(lsb_release -cs) main restricted universe multiverse" > /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt $(lsb_release -cs)-updates main restricted universe multiverse" …
Run Code Online (Sandbox Code Playgroud)

ubuntu apt docker

3
推荐指数
2
解决办法
1万
查看次数