我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上编译.而且,虚函数调用有效,因为它是公共继承.因此,我们有封装侵犯,因为从演员Derived到Base应该无法访问.任何人都可以解释为什么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
从我的角度来看,我发现了很奇怪的行为:函数默认参数不能在下面的代码中转发.
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报告相同的错误.
任何人都可以解释一下吗?
如何为CMake指定目标平台?例如x86,x64,amd64.我试过TARGET_CPU=x64但不确定它是否有效.
我试图以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?
以下代码打印“I'm B!”。这有点奇怪,因为B::foo()是私人的。关于A* ptr我们可以说它的静态类型是A(foo公共的),而它的动态类型是B(foo私有的)。所以我可以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) 以下代码无法编译.因为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?我想让第一个代码工作,而不需要管理工作量的开销.解决问题的最佳做法是什么?
让我们考虑一些合成但富有表现力的例子.假设我们有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) 通常,如果我想模拟某些工作或等待确切的时间间隔,我会使用condition_variable::wait_for或者最坏的情况thread::this_thread::sleep_for.但condition_variable 文档说明wait_for或wait_until方法可能会阻止比请求更长的时间.
由于调度或资源争用延迟,此函数可能会阻塞超过timeout_duration.
可以保证多少精确的等待间隔?
UPDATE
我可以不用到达condition_variable吗?
c++ ×8
c++11 ×2
boost ×1
c++14 ×1
cmake ×1
inheritance ×1
lambda ×1
overriding ×1
templates ×1
travis-ci ×1
unique-ptr ×1