小编sus*_*att的帖子

在STL map/set中end()是否必须是常量?

标准中的§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

如果这也不行,有什么怎么办留有余地无效邻居价值?

c++ iterator stl

34
推荐指数
3
解决办法
2554
查看次数

为什么std :: exception在VC++中有额外的构造函数?

我刚才注意到的事情.定义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)

exceptionMSDN中的定义:

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使用未定义的消息创建泛型).

我知道这是非常微不足道的,但仍然存在.有这么好的理由吗?

c++ standards visual-c++

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

我可以告诉编译器考虑关于返回值关闭的控制路径吗?

说我有以下功能:

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,但我也很好奇其他人),为了这个检查的目的,要忽略某个控制路径,而不是完全抑制警告或返回一个无意义的假人功能结束时的值?

c++ warnings g++ visual-studio-2010

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

OpenCV在分配const引用时逃脱了吗?

我偶然发现了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)

c++ opencv const reference

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

如何使Win32/MFC线程循环锁定?

我是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++ mfc multithreading

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

如果没有执行我的模板专业化为什么会被编译?

注意:我知道我在这里做的很多事情在C++ 11中会更容易,但我不能在我的项目中使用它.

我正在制作一个内容管理系统.基本要求是:

  1. 必须能够定义包含任意数量向量的"内容持有者"类,每个向量包含不同类型的值.例如,IntHolder可以持有一个vector<int>,FloatAndBoolHolder可以持有一个vector<float>和一个vector<bool>,等等.
  2. 内容持有者类必须有一个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

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

如何限制类/结构,以便只存在某些预定义的对象?

假设您的程序需要跟踪一年中的几个月.每个月都有一个名称和天数.显然,这是您希望在编译时定义的信息,并且您希望限制程序,以便在运行时期间不能定义其他月份信息.当然,您希望方便地访问月份数据而无需复杂的方法调用.这些信息的典型用例将大致如下:

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供公众审查,但欢迎其他解决方案.

c++ class-design

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

反序列化已知超类的随机派生类

我是序列化的新手,所以这可能是一个简单的问题,但我的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变量,使用它来实例化正确的子类,并将序列化对象读入其中.这会有用吗?有没有更好的办法?

java inheritance serialization

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

有没有办法输入这个?

简化版代码:

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方法的情况下输入每个定义中的每一个?

c++ typedef

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

我可以避免由特定类定义的限定名称吗?

假设我有一个沿着以下行的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::任何地方省略资格.这可能吗?

c++ enums naming scope class

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

弄清楚是什么让VS ++中的C++类抽象化

我正在使用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能以某种方式为我做这件事吗?有关精确定位类定义的确切部分以使其抽象的一般提示吗?

c++ abstract-class visual-studio-2008 visual-studio

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

为什么在程序中调用这个拷贝构造函数?

#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)

c++

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