小编Vik*_*tor的帖子

为什么Visual Studio编译器允许在此示例中违反私有继承?

std::unique_ptr在Visual Studio 2013和2017中发现了非常奇怪的行为.让我们考虑一个例子:

class Base 
{
public:
    virtual ~Base() = default;
    virtual void Foo() = 0;
};

class Derived : private Base 
{
public:
    void Foo() override
    {
        std::cout << "Foo";
    }
};

void Foo(std::unique_ptr<Base> a)
{
    a->Foo();
}

Foo(std::unique_ptr<Base>(new Derived())); // Compiles
Run Code Online (Sandbox Code Playgroud)

请注意,继承是私有的.此示例仅在Visual Studio上编译.而且,虚函数调用有效,因为它是公共继承.因此,我们有封装侵犯,因为从演员DerivedBase应该无法访问.任何人都可以解释为什么Visual Studio允许这样做?这是一个已知的问题吗?

由于合理的原因,下面的行无法编译.第一个和第二个用法之间的唯一区别在于第二个,B创建了命名对象.

std::unique_ptr<Base> B(new Derived()); // Doesn't compile
Run Code Online (Sandbox Code Playgroud)

是否与此问题有关,仍然没有修复?

c++ encapsulation unique-ptr visual-studio private-inheritance

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

为什么函数默认参数不能在C++中转发?

从我的角度来看,我发现了很奇怪的行为:函数默认参数不能在下面的代码中转发.

void Test(int test = int{}) {}

template<typename F, typename ...Args>
void Foo(F&& f, Args&&... args)
{
    std::forward<F>(f)(std::forward<Args>(args)...);
}

int main()
{
    Foo(Test, 0); // This compiles
    Foo(Test);    // This doesn't compile
}
Run Code Online (Sandbox Code Playgroud)

Clang报告:错误:函数调用的参数太少,预期为1,有0个GCC,VC报告相同的错误.

任何人都可以解释一下吗?

代码在这里:http: //rextester.com/live/JOCY22484

c++ perfect-forwarding c++11

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

CMake:如何指定目标平台?

如何为CMake指定目标平台?例如x86,x64,amd64.我试过TARGET_CPU=x64但不确定它是否有效.

c++ cmake

5
推荐指数
3
解决办法
6401
查看次数

如何在Travis CI中使用最新的Boost版本?

我试图以boost 1.64多种方式在Travis CI环境中进行安装。但是他们都没有成功。在我的第一次天真尝试中,我只是在travis脚本中添加了以下行:

install:
  - sudo apt-get install libboost1.64-all-dev
Run Code Online (Sandbox Code Playgroud)

结果是错误消息:找不到软件包libboost1.64-all-dev

在第二次尝试中,我指定了具有必要boost版本的存储库。

before_install:
  - sudo add-apt-repository -y ppa:nschloe/boost-nightly
  - sudo apt-get update -qq
install:
  - sudo apt-get install libboost-all-dev
  # - sudo apt-get install libboost1.64-all-dev (also tried)
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,boost已安装默认版本(1.54)。在第二种情况下,结果是相同的错误消息:找不到软件包libboost1.64-all-dev

在第三次尝试中,我手动输入了安装说明boost

install:
  - sudo wget -O boost_1_64_0.tar.gz http://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_64_0.tar.gz/download
  - sudo tar xzvf boost_1_64_0.tar.gz
  - cd boost_1_64_0/
  - sudo ./bootstrap.sh --prefix=/usr/local
  - sudo ./b2
  - sudo ./b2 install 
Run Code Online (Sandbox Code Playgroud)

结果,我的脚本花费了30多分钟,然后被终止。除了默认的Boost版本以外,是否有任何简单(或仅可行)的方法将其安装到Travis CI?

c++ boost travis-ci

5
推荐指数
2
解决办法
2145
查看次数

为什么重写虚函数时不考虑访问限定符?

以下代码打印“I'm B!”。这有点奇怪,因为B::foo()是私人的。关于A* ptr我们可以说它的静态类型是Afoo公共的),而它的动态类型是Bfoo私有的)。所以我可以foo通过指向 的指针调用A。但这样我就可以访问B. 是否可以视为违反封装性?

由于访问限定符不是类方法签名的一部分,因此可能会导致这种奇怪的情况。为什么在 C++ 中重写虚函数时不考虑访问限定符?我可以禁止此类情况吗?这个决定背后的设计原则是什么?

活生生的例子

#include <iostream>

class A
{
public:
    virtual void foo()
    {
        std::cout << "I'm A!\n";
    };
};

class B: public A
{
private:
    void foo() override
    {
        std::cout << "I'm B!\n";
    };
};

int main()
{
    A* ptr;
    B b;

    ptr = &b;

    ptr->foo();
}
Run Code Online (Sandbox Code Playgroud)

c++ inheritance overriding virtual-functions

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

为什么lambda对象中的局部变量是const?

以下代码无法编译.因为pt有类型const std::packaged_task<void()>>operator()不是const.

auto packagedTask = std::packaged_task<void()>>([]{});
auto future = packagedTask.get_future();
auto function = [pt = std::move(packagedTask)]{ (*pt)(); });
Run Code Online (Sandbox Code Playgroud)

这是解决方法:

auto packagedTask = std::make_shared<std::packaged_task<void()>>([]{});
auto future = packagedTask->get_future();
auto function = [pt = std::move(packagedTask)]{ (*pt)(); });
Run Code Online (Sandbox Code Playgroud)

为什么lambda对象中的局部变量是const?我想让第一个代码工作,而不需要管理工作量的开销.解决问题的最佳做法是什么?

c++ lambda c++14

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

为什么C++链接器对ODR违规没有提及?

让我们考虑一些合成但富有表现力的例子.假设我们有Header.h:

那么header1.h

#include <iostream>

// Define generic version
template<typename T>
inline void Foo()
{
    std::cout << "Generic\n";
}
Run Code Online (Sandbox Code Playgroud)

Header2.h

void Function1();
Run Code Online (Sandbox Code Playgroud)

Header3.h

void Function2();
Run Code Online (Sandbox Code Playgroud)

Source1.cpp

#include "Header1.h"
#include "Header3.h"

// Define specialization 1
template<>
inline void Foo<int>()
{
    std::cout << "Specialization 1\n";
}

void Function1()
{
    Foo<int>();
}
Run Code Online (Sandbox Code Playgroud)

后来我或其他人在另一个源文件中定义了类似的转换.Source2.cpp

#include "Header1.h"

// Define specialization 2
template<>
inline void Foo<int>()
{
    std::cout << "Specialization 2\n";
}

void Function2()
{
    Foo<int>();
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "Header2.h"
#include "Header3.h"

int main()
{
    Function1();
    Function2(); …
Run Code Online (Sandbox Code Playgroud)

c++ templates one-definition-rule

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

如何保证精确的线程睡眠间隔?

通常,如果我想模拟某些工作或等待确切的时间间隔,我会使用condition_variable::wait_for或者最坏的情况thread::this_thread::sleep_for.但condition_variable 文档说明wait_forwait_until方法可能会阻止比请求更长的时间.

由于调度或资源争用延迟,此函数可能会阻塞超过timeout_duration.

可以保证多少精确的等待间隔?

UPDATE

我可以不用到达condition_variable吗?

c++ condition-variable c++11

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