我一次又一次地遇到由于从 C++ 标准头文件间接包含 C 头文件而导致的命名空间污染问题。例如,在我的 Linux 系统上,gcc(版本 5.1.1)<thread>包含usr/include/bits/sched.h,它声明
extern "C" {
extern int clone(int (*__fn) (void *__arg), void *__child_stack, int __flags, void *__arg, ...) throw();
}
Run Code Online (Sandbox Code Playgroud)
在下面的最小示例中
#include <thread> // indirect inclusion of <sched.h>
namespace {
struct foo
{ virtual foo*clone() const=0; };
foo*clone(std::unique_ptr<foo> const&); // function intended
struct bar : foo
{
std::unique_ptr<foo> daughter;
bar(foo*d) : daughter(d) {}
foo*clone() const
{ return new bar(::clone(daughter)); } // to be called here
};
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨调用::clone()与定义不匹配 …
我正在努力让这项工作正常进行,但似乎有一些我不完全理解的事情。
\n\n我在一个文件中有一个多线程应用程序(2个类和我在其中创建线程和所有内容的真正的主程序)。我想分成3个文件。一个用于每个类(及其标题),一个用于主类。
\n\n我有几个 mutices 和一个队列来在线程之间共享消息并随时锁定和解锁它们。
\n\n我想编写一个单例类,以便所有类都可以共享互斥锁:
\n\n标头:
\n\n#ifndef COMMONSINGLETON_H\n#define COMMONSINGLETON_H\n\n#include <mutex> // std::mutex\n#include <queue>\n\nclass CommonSingleton{\n private:\n static std::mutex mutex_w_b;\n //static std::mutex mutex_wifi_ok;\n //static std::queue <std::string> queue_w_b;\n\n public:\n static CommonSingleton& getInstance();\n std::mutex GetMutexWB();\n //std::mutex GetMutexWiFiOk();\n //std::queue <std::string> GetQueueWB();\n private:\n CommonSingleton() {};\n CommonSingleton(CommonSingleton const&);\n void operator=(CommonSingleton const&);\n};\n#endif\nRun Code Online (Sandbox Code Playgroud)\n\n我的 .cpp 文件:
\n\n#include "commonsingleton.h"\n\nstatic CommonSingleton& CommonSingleton::getInstance(){\n static CommonSingleton instance;\n return instance;\n}\nstd::mutex CommonSingleton::GetMutexWB(){\n return mutex_w_b;\n}\n/*std::mutex CommonSingleton::GetMutexWiFiOk(){\n return mutex_wifi_ok;\n}\nstd::queue <std::string> CommonSingleton::GetQueueWB(){\n return queue_w_b;\n}*/\nRun Code Online (Sandbox Code Playgroud)\n\n在我的主要内容中,我有这个来测试互斥体:
\n\nCommonSingleton::getInstance().GetMutexWB.lock();\nRun Code Online (Sandbox Code Playgroud)\n\n但现在我评论了,只是为了弄清楚如何编译。这是我得到的错误: …
作为对我上一个问题的回答,建议尽可能使用std::common_type<X,Y>::type自动返回类型的声明而不是原始的decltype().但是,这样做我遇到了问题(使用gcc 4.7.0).请考虑以下简单代码
template<typename> class A;
template<typename X> class A {
X a[3];
template <typename> friend class A;
public:
A(X a0, X a1, X a2) { a[0]=a0; a[1]=a1; a[2]=a2; }
X operator[](int i) const { return a[i]; }
X operator*(A const&y) const // multiplication 0: dot product with self
{ return a[0]*y[0] + a[1]*y[1] + a[2]*y[2]; }
template<typename Y>
auto operator*(A<Y> const&y) const -> // multiplication 1: dot product with A<Y>
#ifdef USE_DECLTYPE
decltype((*this)[0]*y[0])
#else …Run Code Online (Sandbox Code Playgroud) 以下简单代码没有给出gcc 4.7.0的预期结果.这是正确的还是错误的?
unsigned count_err(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
// enables to reuse the lambda later (not in this simple example)
auto f = [&] (unsigned i) { if(i&mask) ++c; };
#pragma omp parallel for reduction(+:c)
for(unsigned i=0; i<num.size(); ++i)
f(num[i]);
return c;
}
Run Code Online (Sandbox Code Playgroud)
这返回零:c没有完成lambda函数的减少.顺便说一句,我期望结果是串行函数返回的结果
unsigned count_ser(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
auto f = [&] (unsigned i) { if(i&mask) ++c; };
std::for_each(num.begin(),num.end(),f);
return c;
}
Run Code Online (Sandbox Code Playgroud)
以下实现给出了预期的结果(在这两种情况下,执行减少变量增量的代码定义被移动到并行区域)
unsigned count_ok1(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
auto …Run Code Online (Sandbox Code Playgroud) 我仍然对std::vector在C++ 11中使用的类型的要求感到困惑,但这可能是由错误的编译器(gcc 4.7.0)引起的.这段代码:
struct A {
A() : X(0) { std::cerr<<" A::A(); this="<<this<<'\n'; }
int X;
};
int main()
{
std::vector<A> a;
a.resize(4);
}
Run Code Online (Sandbox Code Playgroud)
工作正常并产生预期的输出,表明默认的ctor(显式给定)被调用(而不是隐式复制ctor).但是,如果我将删除的副本ctor添加到课程中,即
struct A {
A() : X(0) { std::cerr<<" A::A(); this="<<this<<'\n'; }
A(A const&) = delete;
int X;
};
Run Code Online (Sandbox Code Playgroud)
gcc 4.7.0不编译,但尝试使用已删除的ctor.这是正确的行为还是错误?如果是前者,如何让代码工作?
我有3节课
class A
{
A();
virtual ~A();
}
class B : public A
{
B();
~B();
}
class C
{
void *obj;
C() : obj(nullptr) {}
~C() { if (obj) delete obj; }
}
Run Code Online (Sandbox Code Playgroud)
当我使用class C作为类的任何子类的容器A并尝试删除C实例时.A,B析构函数是不是很正常?什么是solutuon?
C* instance = new C();
instance.obj = new B();
//Magic
delete instance; // A and B destructor is not called
Run Code Online (Sandbox Code Playgroud) 这个简单的代码
bool foo(std::istringstream&stream, std::string&single, char del)
{ return std::getline(stream,single,del); }
Run Code Online (Sandbox Code Playgroud)
用gcc(4.8.2),但不与铛编译(3.4,使用的libc ++),其抱怨有从没有可行转换std::basic_istream<char, std::char_traits<char> >到bool.但是,当我将参数包装到一个return语句中时static_cast<bool>(),clang很高兴.
这让我感到困惑让我想知道上面的代码是否形成良好,即gcc或clang是否正确.根据cpprefernce std::getline返回a std::basic_istream<char, std::char_traits<char> >,它继承自std::basic_ios具有类型转换的operator bool(因为C++ 11,在它进行类型转换之前void*).不应该自动选择此转换运算符吗?(出于某种原因,我更愿意接受gcc错误而不是clang).
编辑我刚才发现显然llvm的libc ++声明了有问题的转换运算符explicit,认为它对隐式转换无效.这符合标准吗?
我很难打包std::stoll成一个std::function.天真
std::function<std::int64_t(std::string const&)> obj = std::stoll;
Run Code Online (Sandbox Code Playgroud)
失败,因为std::stoll是两个函数的重载(cppreference没有提到[在询问的时候]),一个将std::string另一个std::wstring作为第一个参数.那么我怎么得到我想要的东西?
我知道我可以使用lambda来调用std::stoll,但我正在寻找表单的解决方案
auto parser = ???
std::function<std::int64_t(std::string const&)> obj{parser};
Run Code Online (Sandbox Code Playgroud) 我有一个指针定义如下:
A ***b;
Run Code Online (Sandbox Code Playgroud)
按如下方式访问它:
A** c = b[-1]
Run Code Online (Sandbox Code Playgroud)
它是否是访问冲突,因为我们对数组使用负索引?或者它是一个类似的合法操作*--b?
编辑请注意,负数组索引在C和C++中具有不同的支持.因此,这不是一个骗局.
我有一个模板构建器/工厂类,它使对象成为类型Foo,其中make()方法是模板方法,如下所示:
template<typename T1>
class FooMaker
{
template<typename T2>
Foo make(...) { ... }
};
Run Code Online (Sandbox Code Playgroud)
这里的想法T1是绑定到构建器,因为它对于所有make()调用都是相同的,而T2(对于每个调用,它总是一个函数名)通常是不同的make().
我make()多次调用创建不同类型的对象,模板类和模板函数的组合意味着我必须template在每次调用之前使用消歧器:
template <typename MAKER_T>
void make_some_foos()
{
auto maker = FooMaker<MAKER_T>(...);
Foo foo1 = maker.template make<Type1>(...);
Foo foo2 = maker.template make<Type2>(...);
// etc...
}
Run Code Online (Sandbox Code Playgroud)
我想template在构造Foo上面的每一行上都需要关键字.一般来说,我make()对每个FooMaker对象都有很多调用,因此在创建工厂时会有少量额外的代码.
显然,我可以做到这一点使用它可以隐藏宏template细节,但有一个良好的非宏解决方案1?
1我能够继续前进T1,并T2在同一水平-使它们既类模板参数,或两者功能模板参数,但前者需要一个不同的制造商为每一个新的类型T2,而后者的手段冗余指定相同的T1 …
c++ ×10
c++11 ×7
pointers ×2
allocation ×1
arrays ×1
clang ×1
constructor ×1
containers ×1
decltype ×1
destruction ×1
gcc ×1
lambda ×1
mutex ×1
namespaces ×1
openmp ×1
overloading ×1
std-function ×1
stdvector ×1
templates ×1
type-traits ×1