小编Sta*_*ked的帖子

序列化C风格的结构(使用C++)

使用memcpy序列化struct对象是不是很邪恶?

在我的一个项目中,我正在执行以下操作:我记住一个struct对象,base64对其进行编码,然后将其写入文件.我在解析数据时做了反向.它似乎工作正常,但在某些情况下(例如,当使用WINDOWPLACEMENTWindows Media Player的HWND时),事实证明解码数据不匹配sizeof(WINDOWPLACEMENT).

以下是一些代码片段:

// Using WINDOWPLACEMENT from Windows API headers:
typedef struct tagWINDOWPLACEMENT {
    UINT  length;
    UINT  flags;
    UINT  showCmd;
    POINT ptMinPosition;
    POINT ptMaxPosition;
    RECT  rcNormalPosition;
#ifdef _MAC
    RECT  rcDevice;
#endif
} WINDOWPLACEMENT;


static std::string EncodeWindowPlacement(const WINDOWPLACEMENT & inWindowPlacement)
{
    std::stringstream ss;
    {
        Poco::Base64Encoder encoder(ss); // From the Poco C++ libraries
        const char * offset = reinterpret_cast<const char*>(&inWindowPlacement);
        std::vector<char> buffer(offset, offset + sizeof(inWindowPlacement));
        for (size_t idx = 0; idx != buffer.size(); ++idx)
        {
            encoder …
Run Code Online (Sandbox Code Playgroud)

c c++ serialization

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

将函数指针作为模板参数传递

出于教育目的,我正在尝试编写自己的"ForEach"函数:

#include <iostream>
#include <string>
#include <vector>


//
// This works
//
template<class Container>
void ForEach_v1(const Container & inContainer, void (*Functor)(const std::string &))
{
    typename Container::const_iterator it = inContainer.begin(), end = inContainer.end();
    for (; it != end; ++it)
    {
        Functor(*it);
    }
}


//
// Does not work
//
template<class Container, class Functor>
void ForEach_v2(const Container & inContainer, Functor inFunctor)
{
    typename Container::const_iterator it = inContainer.begin(), end = inContainer.end();
    for (; it != end; ++it)
    {
        Functor(*it);
    }
}

void PrintWord(const …
Run Code Online (Sandbox Code Playgroud)

c++

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

REST API 适合交互式软件或游戏吗?

具体来说,我想知道是否可以使用 REST API 实现基于网络的俄罗斯方块游戏。资源将是:current-blockgridscore等...移动块将是对current-block资源的 POST 请求,并将参数嵌入到请求正文中。要获取当前游戏状态,将使用 GET 请求,等等......

这样做有意义吗?

rest

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

尝试创建临时对象时出现奇怪的编译器错误

发布此问题后,我尝试重现创建范围RAII对象时意外右值创建的问题.现在看来我没有编译器错误就无法重现它!

在下面的代码示例中,在Test::foo()第二个ScopedLock创建中没有编译.gcc编译器错误似乎完全错误.谁能解释一下?

struct Mutex
{
    void lock() { }

    void unlock() { }
};


struct ScopedLock
{
    ScopedLock(Mutex & inMutex) : mMutex(inMutex)
    { mMutex.lock(); }

    ~ScopedLock()
    { mMutex.unlock(); }

private:
    ScopedLock(const ScopedLock&);
    ScopedLock& operator=(const ScopedLock&);

    Mutex mMutex;
};


struct Test
{
    void foo()
    {
        // Compiles fine
        ScopedLock lock(mMutex);

        // Error: no matching function for
        // call to ‘ScopedLock::ScopedLock()’
        ScopedLock(mMutex);
    }

    Mutex mMutex;
};
Run Code Online (Sandbox Code Playgroud)

我在Mac上使用GCC 4.2.1.

更新

我查看了原始代码,发现该成员是通过this指针引用的:

ScopedLock(this->mMutex); // short-lived temporary and compiles …
Run Code Online (Sandbox Code Playgroud)

c++ most-vexing-parse

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

常见智能指针的.reset()方法

在我看来,boost scoped_ptr和shared_ptr中的reset方法导致构造和销毁的错误顺序:

boost::scoped_ptr<Component> component(GetDefaultComponent());
component.reset(new BetterComponent); // 1. Creation of the new object
                                      // 2. Destruction of the old object
Run Code Online (Sandbox Code Playgroud)

这是IMO的错误订单.

可以先调用不带参数的reset方法,然后设置新指针.然而,这对我来说似乎是一种解决方法.(它是一种"解决方法"意味着存在错误.)

我相信,提振人非常聪明.因此,目前的方法必须有理由.

有谁知道更多?

c++

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

小的ref-counting缓冲类中的内存损坏

我有一个简单的引用计数类,它包含一个内存缓冲区.它看起来像这样:

#include <algorithm>

template<typename T>
struct buffer
{
    // create a buffer of length n
    buffer(unsigned n) : rc(*(new unsigned(1))), data(new T[n]) { }

    buffer(const buffer<T> & rhs) : rc(++rhs.rc), data(rhs.data) { }

    buffer<T>& operator=(buffer<T> rhs)
    {
        std::swap(rc, rhs.rc);
        std::swap(data, rhs.data);
        return *this;
    }

    ~buffer()
    {
        if (--rc == 0) {
            delete [] data;
            delete (&rc);
        }
    }

private:
    mutable unsigned & rc;
    T * data;
};


int main() {
    typedef buffer<int> numbers;
    numbers n1(10);
    numbers n2(20);
    numbers n3(30);
    n1 …
Run Code Online (Sandbox Code Playgroud)

c++

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

如果我取消引用空指针,为什么操作系统不会崩溃?

取消引用空指针会导致未定义的行为.在实践中,它通常意味着我的程序会崩溃.但为什么操作系统不会崩溃?因为如果我的程序取消引用空指针,并且我的程序由操作系统运行,那么,根据逻辑传递性规则,这意味着操作系统试图取消引用空指针.为什么OS不进入"未定义行为"状态?

c++

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

通用参考和本地课程

在我的下面的代码中,我有一个接受"通用引用"(F&&)的函数.该函数还有一个内部类,它接受F&&构造函数中的对象.是F&&仍然在这一点上通用的参考?即F仍然被认为是推断类型?

换句话说,我应该使用std::forward<F>std::move在构造函数初始化列表中?

#include "tbb/task.h"
#include <iostream>
#include <future>

template<class F>
auto Async(F&& f) -> std::future<decltype(f())>
{
    typedef decltype(f()) result_type;

    struct Task : tbb::task
    {
        Task(F&& f) : f_(std::forward<F>(f)) {} // is forward correct here?

        virtual tbb::task* execute()
        {
            f_();
            return nullptr;
        }

        std::packaged_task<result_type()> f_;
    };

    auto task = new (tbb::task::allocate_root()) Task(std::forward<F>(f));
    tbb::task::enqueue(*task);
    return task->f_.get_future();
}


int main()
{
    Async([]{ std::cout << "Hi" << std::endl; }).get();
}
Run Code Online (Sandbox Code Playgroud)

现场演示.

c++ forwarding forward perfect-forwarding forwarding-reference

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

如何在C++ std :: set中放置看似无法比较的对象?

假设我想将标识服务器的对象放入stl中set.然后我必须确保我也operator<为这些对象实现,否则我会遇到编译器错误:

struct ServerID
{
  std::string name; // name of the server
  int port;
};

std::set<ServerID> servers; // compiler error, no operator< defined
Run Code Online (Sandbox Code Playgroud)

这只是我想要使对象具有可比性的常见问题的一个例子.

我目前的解决方案通常是这样的:

bool operator< (const ServerID & lhs, const ServerID & rhs)
{
  if (lhs.name != rhs.name)
  {
    return lhs.name < rhs.name;
  }
  else
  {
    return lhs.port < rhs.port;
  }
}
Run Code Online (Sandbox Code Playgroud)

这只是我发现自己的解决方案.但我怀疑这个问题也可能在计算机科学中得到认可.所以,如果我很幸运,有一个更好的解决方案.任何人都可以向我暗示吗?

c++ algorithm

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

Bash脚本键盘输入

我正在创建一个用于生成证书的bash脚本.创建证书的openssl命令要求输入键盘.这是每次相同的键序列:七次[ENTER]后跟两次['y'+ ENTER].我该如何以编程方式执行此操作?

更新

我能够使用命令行参数减少消除所需的键盘输入:

  • -config FILE 指定配置文件
  • -passin PWD-passout PWD指定密码

有关详细信息,您可以查看我的实验.这个网址可以通过颠覆来结账.

bash shell

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