我已经读过weak_pointers可以用来打破循环引用.
请考虑以下循环引用示例
struct A
{
boost::shared_ptr<A> shrd_ptr;
};
boost::shared_ptr<A> ptr_A(boost::make_shared<A>());
boost::shared_ptr<A> ptr_b(boost::make_shared<A>());
ptr_A->shrd_ptr = ptr_b;
ptr_b->shrd_ptr = ptr_A;
Run Code Online (Sandbox Code Playgroud)
现在上面是一个循环引用的例子,我想知道如何通过使用来打破上面的循环引用weak_ptr?
更新:根据收到的建议,我想出了以下内容:
struct A
{
boost::weak_ptr<A> wk_ptr;
};
boost::shared_ptr<A> ptr_A (boost::make_shared<A>());
boost::shared_ptr<A> ptr_B (boost::make_shared<A>());
ptr_A->wk_ptr = ptr_B;
ptr_B->wk_ptr = ptr_A;
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?
在C面向条件运营商求值1或0类型的int(即使它确实有专用_Bool型).参考C11 N1570草案:
C11§6.5.8/ 6 关系运算符
如果指定的关系为真,则每个运算符
<(小于),>(大于),<=(小于或等于)和>=(大于或等于)将产生1,如果为假,则为0.107)结果有类型int.C11§6.5.9/ 3 平等运营商
的
==(等于)和!=(不等于)运算符类似于除了它们的优先级低的关系运算符.108)如果指定的关系为真,则每个运算符产生1,如果为假,则产生0.结果有类型int.对于任何一对操作数,其中一个关系是正确的.C11 6.5.13/3 逻辑AND运算符
该
&&运营商将产生1,如果两个操作数的比较不等于0; 否则,它产生0.结果有类型int.C11 6.5.14/3 逻辑OR运算符
该
||操作人员应得到1如果任一操作数的比较不等于0; 否则,它产生0.结果有类型int.
正如我检查的那样,C++似乎在这个问题上有所不同,如下面的示例所示(请参阅http://ideone.com/u3NxfW):
#include <iostream>
#include <typeinfo>
int main() {
double x = 10.0;
std::cout << typeid(x <= 10.0).name() << std::endl;
return …Run Code Online (Sandbox Code Playgroud) 重载运算符的标准C++ 03语法如下:
operator-function-id:
运算 符运算符
运算 符 < template-argument-list?>
第一个是我们通常使用的普通运算符重载语法,例如
Myclass operator + (Myclass s) {...}
Run Code Online (Sandbox Code Playgroud)
但第二种选择意味着什么呢?特别是,在什么情况下我们使用template-argument-list?在快速浏览一下C++ 11之后,我发现第二种形式已经从标准中删除了.它的初衷是什么?
编辑:使用VC++ 2010测试后,下面是使用上述语法的一种方法,虽然它对我没有多大意义:
class K {
public:
int a;
template <int B>
int operator + (int b) {
return a+b+B;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
K k;
k.a=1;
int s;
s=k.operator+<115>(2);
printf("%d\n",s);
return 0;
}
output:118
Run Code Online (Sandbox Code Playgroud) 我记得读过在方法中声明的静态变量不是线程安全的.(请参阅托德加德纳提到的梅耶的单身人士怎么样)
Dog* MyClass::BadMethod()
{
static Dog dog("Lassie");
return &dog;
}
Run Code Online (Sandbox Code Playgroud)
我的库为最终用户生成C++代码,以便作为其应用程序的一部分进行编译.它生成的代码需要以线程安全的跨平台方式初始化静态变量.我想使用boost::call_once互斥变量初始化,但最后用户会暴露于Boost依赖项.
有没有办法让我这样做而不强迫最终用户有额外的依赖?
对于某些整数类型,即使浮点值远远超出整数的可表示范围,如何找到最接近某个浮点类型值的值.
或者更确切地说:
我们F是一个浮点型(可能是float,double或long double).让I是一个整数类型.
假设两个F并I有有效的专业化std::numeric_limits<>.
给定可表示的值F,并且仅使用C++ 03,如何找到最接近的可表示值I?
我追求的是一个纯粹,高效且线程安全的解决方案,除了C++ 03所保证的以外,它不会对平台做任何假设.
如果不存在这样的解决方案,是否可以使用C99/C++ 11的新功能找到一个?
lround()由于报告域错误的非平凡方式,使用C99似乎是有问题的.这些域错误是否可以以便携式和线程安全的方式捕获?
注意:我知道Boost可能通过其boost::numerics::converter<>模板提供解决方案,但由于其高复杂性和冗长性,我无法从中提取必需品,因此我无法检查他们的解决方案是否成功超出C++ 03的假设.
下面的天真方法失败了,因为I(f)当C++ 03的整数部分f不是可表示的值时,结果是未定义的I.
template<class I, class F> I closest_int(F f)
{
return I(f);
}
Run Code Online (Sandbox Code Playgroud)
然后考虑以下方法:
template<class I, class F> I closest_int(F f)
{
if (f < std::numeric_limits<I>::min()) return std::numeric_limits<I>::min();
if (std::numeric_limits<I>::max() < f) return std::numeric_limits<I>::max();
return I(f);
} …Run Code Online (Sandbox Code Playgroud) 该constexpr关键字是在C++ 11中引入的,因为(我认为)是"常量表达式"的相应概念.但是,这个概念隐含在C++ 98/c ++ 03中,因为数组声明需要一个常量表达式:
// valid:
int a[sizeof(int)];
int b[3+7];
int c[13/4];
const int n = 3;
int d[n];
// invalid:
int m = 4;
int e[m];
Run Code Online (Sandbox Code Playgroud)
还有其他"常量表达式",即可以在编译时评估(和/或必须)的表达式; 一个例子是模板参数.
对于预C++ 11,在C++ 98/03标准或其他地方是否存在以下情况?
什么是适当的I/O标志集std::fstream,我希望能够读取和写入文件,而不截断文件(如果存在),但如果不存在则创建它?
我试过了
std::ios::binary | std::ios::in | std::ios::out
std::ios::binary | std::ios::in | std::ios::out | std::ios::ate
Run Code Online (Sandbox Code Playgroud)
但如果文件尚不存在,则这些文件都不会创建.
我不想要std::ios::app,因为我还需要能够随意搜索文件,包括get和put游标.
我认为,一种解决方法是实例化std::ofstream第一个,然后立即关闭它并打开我真正想要的流,但如果可以通过单个流对象避免它,那似乎很麻烦.
给定POD结构(在C++ 03中)或标准布局类型(在C++ 11中),所有成员都具有基本对齐要求,是否保证每个成员根据其对齐要求进行对齐?
换句话说,对于m_k{ m0... mn}标准布局类型的所有成员S,
struct S {
T0 m0;
T1 m1;
...
TN mn;
};
Run Code Online (Sandbox Code Playgroud)
是否保证评估以下表达式true?
(offsetof(S,m_k) % alignof(decltype(S::m_k))) == 0
Run Code Online (Sandbox Code Playgroud)
请给出C++ 03和C++ 11的答案,并引用标准的相关部分.支持C标准的证据也会有所帮助.
我对C++ 03标准(ISO/IEC 14882:2003(E))的阅读是关于POD结构中成员的对齐,除了第一个成员之外,它是静默的.相关段落是:
在规范的语言中,对象是"存储区域":
1.8 C + +对象模型[intro.object]
1.8/1 C++程序中的构造创建,销毁,引用,访问和操作对象.对象是存储区域....
根据对齐要求分配对象:
3.9类型[basic.types]
3.9/5对象类型具有对齐要求(3.9.1,3.9.2).完整对象类型的对齐是表示字节数的实现定义的整数值; 在满足其对象类型的对齐要求的地址处分配对象.
基本类型具有对齐要求:
3.9.1基本类型[basic.fundamental]
3.9.1/3对于每个有符号整数类型,存在相应的(但不同的)无符号整数类型:"unsigned char","unsigned short int","unsigned int"和"unsigned long int",每个它占用相同的存储量,并且具有与相应的有符号整数类型相同的对齐要求(3.9) ; ...
由于"实现对齐要求",可能会发生填充:
9.2班级成员[class.mem]
9.2/12声明没有插入访问说明符的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址.由访问说明符分隔的非静态数据成员的分配顺序未指定(11.1).实现对齐要求可能导致两个相邻成员不会立即分配 ; 因此,可能需要空间来管理虚拟功能(10.3)和虚拟基类(10.1).
9.2/12中的"已分配"一词与3.9/5中的"已分配"含义相同吗?规范中"分配"的大多数用法是指动态存储分配,而不是结构内部布局.使用可能在9.2/12中似乎意味着结构成员可能不严格要求3.9/5和3.9.1/3的对齐要求.
POD结构的第一个成员将根据结构的对齐要求进行对齐:
9.2/17指向POD结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然.[ 注意:因此,在POD-struct对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐.]
[重点在上述所有引文中加入.]
我有一个关于卷括号括号列表的不同含义的问题.
我知道C++ 03不支持C++ 11 initializer_list.然而,即使没有-std=c++11编译器标志,gcc 6.3 也会interpolate使用以下代码正确初始化:
map<string, string> interpolate = { { "F", "a && b && c" }, { "H", "p ^ 2 + w" }, { "K", "H > 10 || e < 5" }, { "J", "F && !K" } };
Run Code Online (Sandbox Code Playgroud)
我被问到为什么这会起作用,我意识到我没有答案.这是一个Brace-Init-List,但我们从初始化标准容器的方式通常是通过initializer_list.那么非C++ 11代码如何完成初始化呢?
考虑以下代码:
#define A -100
//later..
void Foo()
{
int bar = -A;
//etc..
}
Run Code Online (Sandbox Code Playgroud)
现在,这可以在我测试的一些主要编译器(MSVC,GCC,Clang)上很好地进行编译,并且bar == 100按预期进行,这是因为所有这些编译器的预处理器在标记之间插入了一个空格,因此您最终得到:
int bar = - -100;
Run Code Online (Sandbox Code Playgroud)
因为我希望代码尽可能地可移植,所以我去检查此行为是否由标准定义,但是我在此上找不到任何东西。这种行为是由标准保证的还是仅仅是编译器功能,是否还bar = --100;允许幼稚的方法(显然不会进行编译)?