标准中的§23.1.2.8声明对set/map的插入/删除操作不会使对这些对象的任何迭代器无效(指向已删除元素的迭代器除外).
现在,考虑以下情况:您希望实现具有唯一编号节点的图形,其中每个节点具有固定数量(假设4个)邻居.利用上述规则,你可以这样做:
class Node {
private:
// iterators to neighboring nodes
std::map<int, Node>::iterator neighbors[4];
friend class Graph;
};
class Graph {
private:
std::map<int, Node> nodes;
};
Run Code Online (Sandbox Code Playgroud)
(编辑:由于Node第4行的不完整性(参见回复/评论),并非字面意思,但无论如何都沿着这些方向)
这很好,因为这样您就可以插入和删除节点而不会使结构的一致性失效(假设您跟踪删除并从每个节点的数组中删除已删除的迭代器).
但是,假设您还希望能够存储"无效"或"不存在"的邻居值.不用担心,我们可以使用nodes.end()...或者我们可以吗?是否存在某种保证,nodes.end()在nodes.end()经过多次插入/删除后,上午8点将与下午10点相同?也就是说,我可以安全地==将作为参数接收的迭代器nodes.end()与Graph的某些方法进行比较吗?
如果没有,这会有效吗?
class Graph {
private:
std::map<int, Node> nodes;
std::map<int, Node>::iterator _INVALID;
public:
Graph() { _INVALID = nodes.end(); }
};
Run Code Online (Sandbox Code Playgroud)
也就是说,我可以nodes.end()在构造时存储变量,然后每当我想将邻居设置为无效状态时使用此变量,或者将它与方法中的参数进行比较吗?或者有可能在某个地方,指向现有对象的有效迭代器将比较等于_INVALID?
如果这也不行,有什么可怎么办留有余地无效邻居价值?
我刚才注意到的事情.定义exception的标准(18.6.1):
class exception {
public :
exception() throw();
exception(const exception &) throw();
exception& operator=(const exception&) throw();
virtual ~exception() throw();
virtual const char* what() const throw();
};
Run Code Online (Sandbox Code Playgroud)
exception在MSDN中的定义:
class exception {
public:
exception();
exception(const char *const&);
exception(const char *const&, int);
exception(const exception&);
exception& operator=(const exception&);
virtual ~exception();
virtual const char *what() const;
};
Run Code Online (Sandbox Code Playgroud)
看起来Microsoft的版本允许您为exception对象指定错误消息,而标准版本只允许您为派生类执行此操作(但不会阻止您exception使用未定义的消息创建泛型).
我知道这是非常微不足道的,但仍然存在.有这么好的理由吗?
说我有以下功能:
Thingy& getThingy(int id)
{
for ( int i = 0; i < something(); ++i )
{
// normal execution guarantees that the Thingy we're looking for exists
if ( thingyArray[i].id == id )
return thingyArray[i];
}
// If we got this far, then something went horribly wrong and we can't recover.
// This function terminates the program.
fatalError("The sky is falling!");
// Execution will never reach this point.
}
Run Code Online (Sandbox Code Playgroud)
编译器通常会抱怨这一点,并说"并非所有控制路径都返回一个值".这在技术上是真实的,但没有返回值的控制路径终止程序函数结束之前,因此是语义正确的.有没有办法告诉编译器(在我的情况下VS2010,但我也很好奇其他人),为了这个检查的目的,要忽略某个控制路径,而不是完全抑制警告或返回一个无意义的假人功能结束时的值?
我偶然发现了openCV源代码中的这段代码(cxoperations.hpp,第1134行,在Vector类的定义中):
Vector(const Vector& d, const Range& r)
{
if( r == Range::all() )
r = Range(0, d.size());
// some more stuff...
}
Run Code Online (Sandbox Code Playgroud)
请注意,Vector该类没有调用数据成员r(实际上,标识符r仅出现在整个类定义中的另一个位置,作为另一个方法中的参数).显然,这是对const参考的任务.
我试图重现一个最小的例子:
#include <iostream>
class Foo
{
public:
int _a;
Foo(int a) : _a(a) {}
};
int main()
{
Foo x(0);
const Foo& y = x;
printf("%d\n", y._a);
y = Foo(3);
printf("%d\n", y._a);
}
Run Code Online (Sandbox Code Playgroud)
当然,这无法编译:g ++给出了错误
test.cpp:15: error: passing `const Foo' as `this' argument of `Foo& …Run Code Online (Sandbox Code Playgroud) 我是Windows中多线程的新手,所以这可能是一个微不足道的问题:确保线程以锁步方式执行循环的最简单方法是什么?
我尝试将一个共享的Events 数组传递给所有线程,并WaitForMultipleObjects在循环结束时使用它们来同步它们,但这会在一个循环(有时是两个循环)之后出现死锁.这是我当前代码的简化版本(只有两个线程,但我想让它可扩展):
typedef struct
{
int rank;
HANDLE* step_events;
} IterationParams;
int main(int argc, char **argv)
{
// ...
IterationParams p[2];
HANDLE step_events[2];
for (int j=0; j<2; ++j)
{
step_events[j] = CreateEvent(NULL, FALSE, FALSE, NULL);
}
for (int j=0; j<2; ++j)
{
p[j].rank = j;
p[j].step_events = step_events;
AfxBeginThread(Iteration, p+j);
}
// ...
}
UINT Iteration(LPVOID pParam)
{
IterationParams* p = (IterationParams*)pParam;
int rank = p->rank;
for (int i=0; i<100; i++)
{
if (rank == …Run Code Online (Sandbox Code Playgroud) 注意:我知道我在这里做的很多事情在C++ 11中会更容易,但我不能在我的项目中使用它.
我正在制作一个内容管理系统.基本要求是:
IntHolder可以持有一个vector<int>,FloatAndBoolHolder可以持有一个vector<float>和一个vector<bool>,等等.get<>()方法.模板参数get<>()是一种类型.如果内容持有者具有该类型的向量,则get<>()必须从该向量返回一个值,否则调用get<>()必须生成编译器错误.例如,如果我有一个IntHolder对象,那么调用get<int>()它将int从其向量返回一个,但调用get<float>()它会产生编译器错误.我设法找到了解决所有这些问题的解决方案.警告,模板递归:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int value = 'A';
// helper struct that saves us from partially specialized method overloads
template < class RequestedType, class ActualType, class TContentHolder >
struct Getter;
// holds a vector of type TContent, recursively inherits from holders of …Run Code Online (Sandbox Code Playgroud) c++ templates template-specialization template-meta-programming
假设您的程序需要跟踪一年中的几个月.每个月都有一个名称和天数.显然,这是您希望在编译时定义的信息,并且您希望限制程序,以便在运行时期间不能定义其他月份信息.当然,您希望方便地访问月份数据而无需复杂的方法调用.这些信息的典型用例将大致如下:
Month m = GetRandomMonth();
if ( m == FEBRUARY )
CreateAppointment(2011, m, 28);
// Iterating over all months would be optional, but a nice bonus
for (/* each month m*/)
cout << "Month " << m.name << " has " << m.num_days << " days." << endl;
Run Code Online (Sandbox Code Playgroud)
而不应该飞的东西包括:
Month m = Month("Jabruapril", 42); // should give compiler error
Month m = MonthService().getInstance().getMonthByName("February"); // screw this
Run Code Online (Sandbox Code Playgroud)
(我故意使代码尽可能模糊,以表示我不限于任何特定的实现方法.)
解决这个问题最优雅的方法是什么?我正在添加自己的aswer供公众审查,但欢迎其他解决方案.
我是序列化的新手,所以这可能是一个简单的问题,但我的google-fu今天很弱.
假设您有以下类:
public class Base implements Serializable {
// ...
}
public class Der1 extends Base {
// ...
}
public class Der2 extends Base {
// ...
}
Run Code Online (Sandbox Code Playgroud)
Alice随机创建一个Der1或两个对象Der2,将其序列化为文件,然后将其发送给Bob.Bob知道这个对象的类是子类Base,但不知道哪一个(他有与Alice有相同的类定义).Bob如何将文件反序列化为适当子类的实例?
我的第一个想法是Alice可以定义一个这样的类:
public DerClass implements Serializable {
public Class<? extends Base> class;
}
Run Code Online (Sandbox Code Playgroud)
她使用它来存储对象的类,将其序列化并将其发送给Bob.Bob DerClass从该文件构造一个对象,读取class变量,使用它来实例化正确的子类,并将序列化对象读入其中.这会有用吗?有没有更好的办法?
简化版代码:
foo.h中:
class Foo {
private:
class Bar {
// ...
};
typedef std::map<int, Bar> mapType;
mapType _map;
public:
void method(mapType::iterator it);
};
Run Code Online (Sandbox Code Playgroud)
Foo.cpp中:
void Foo::method(mapType::iterator it) {
// ...
notMethod(it);
}
void notMethod(mapType::iterator it) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
不出所料,我'mapType' is not a class or namespace name在VS2008 notMethod的定义中得到了错误.是否有任何(优雅的)方式可以避免std::map<int, Bar>在notMethod不改变notMethod方法的情况下输入每个定义中的每一个?
假设我有一个沿着以下行的MessageBox类:
class MyMessageBox
{
public:
enum Priority {
Prior_Dialog,
Prior_Warning,
// ...
};
enum Icon {
Icon_Question,
Icon_Exclamation,
// ...
};
enum Button {
Button_Yes,
Button_No,
Button_Cancel,
// ...
};
static void Show(Priority pPriority, Icon pIcon, Button pButton1, Button pButton2);
// ...
};
Run Code Online (Sandbox Code Playgroud)
现在,如果我想抛出一个消息框,我必须输入MyMessageBox::每个标识符:
MyMessageBox::Show(MyMessageBox::Prior_Dialog, MyMessageBox::Icon_Question, MyMessageBox::Button_Yes, MyMessageBox::Button_No);
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想要一些非宏解决方案,允许源文件#include "MyMessageBox.h"在MyMessageBox::任何地方省略资格.这可能吗?
我正在使用VS2008构建一个普通的旧C++程序(而不是C++/CLI).我有一个抽象基类和一个非抽象派生类,并构建这个:
Base* obj;
obj = new Derived();
Run Code Online (Sandbox Code Playgroud)
失败并显示错误"'Derived':无法实例化抽象类".(但值得注意的是,如果我将鼠标悬停在Base光标上,VS会弹出一个工具提示"class base abstract",但是悬停Derived只会说"class Derived"(没有"抽象")).
这些类的定义相当大,我想避免手动检查每个方法是否已被覆盖.VS能以某种方式为我做这件事吗?有关精确定位类定义的确切部分以使其抽象的一般提示吗?
#include <iostream>
#include <string.h>
using namespace std;
class withCC
{
public:
withCC() {}
withCC(const withCC&) {
cout<<"withCC(withCC&)"<<endl;
}
};
class woCC
{
enum {bsz = 100};
char buf[bsz];
public:
woCC(const char* msg = 0) {
memset(buf, 0, bsz);
if(msg) strncpy(buf, msg, bsz);
}
void print(const char* msg = 0)const {
if(msg) cout<<msg<<":";
cout<<buf<<endl;
}
};
class composite
{
withCC WITHCC;
woCC WOCC;
public:
composite() : WOCC("composite()") {}
void print(const char* msg = 0) {
cout<<"in composite:"<<endl;
WOCC.print(msg);
}
};
int …Run Code Online (Sandbox Code Playgroud)