小编Mih*_*dor的帖子

WIN32_FIND_DATA - 获取绝对路径

我正在使用这样的东西:

std::string tempDirectory = "./test/*";

WIN32_FIND_DATA directoryHandle;
memset(&directoryHandle, 0, sizeof(WIN32_FIND_DATA));//perhaps redundant???

std::wstring wideString = std::wstring(tempDirectory.begin(), tempDirectory.end());
LPCWSTR directoryPath = wideString.c_str();

//iterate over all files
HANDLE handle = FindFirstFile(directoryPath, &directoryHandle);
while(INVALID_HANDLE_VALUE != handle)
{
    //skip non-files
    if (!(directoryHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
    {
        //convert from WCHAR to std::string
        size_t size = wcslen(directoryHandle.cFileName);
        char * buffer = new char [2 * size + 2];
        wcstombs(buffer, directoryHandle.cFileName, 2 * size + 2);
        std::string file(buffer);
        delete [] buffer;

        std::cout << file;
    }

    if(FALSE == FindNextFile(handle, &directoryHandle)) …
Run Code Online (Sandbox Code Playgroud)

c++ windows filesystems directory absolute-path

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

两个类之间的循环引用

我知道这必须是一个n00b问题,但我必须实现一个模型客户端 - 服务器顺序交互应用程序,并且因为客户端 - 服务器调用的数量不同,我不能只是迭代外部函数中的步骤,总是从中获取数据客户端,然后将其转发到服务器,反之亦然,所以我需要让我Server和我们Client相互了解,以便他们可以在自己之间调用他们的公共方法.一种方法是将两者都设计为单身,但我希望以更简单的方式进行,更准确地说使用循环引用:客户端存储对服务器的引用,服务器存储对客户端的引用.我知道这可能不是一个好方法,并且当它变得太深时它可能导致调用堆栈爆炸,因此欢迎对我的设计进行任何改进.

为了实现所描述的实现,我认为我可以使用std::shared_ptr,因为std::unique_ptr当我调用两个setter时,如果我还想阻止main中的两个变量被破坏,那么它将无法工作(对吗?).所以,这就是我所拥有的(简化代码):

#include <iostream>
#include <memory>

class Server;

class Client
{
public:
    void SetServer (const Server &server);
private:
    std::shared_ptr<const Server> server;
};

void Client::SetServer (const Server &server)
{
    this->server = std::shared_ptr<const Server>(&server);
}

class Server
{
public:
    void SetClient (const Client &client);
private:
    std::shared_ptr<const Client> client;
};

void Server::SetClient (const Client &client)
{
    this->client = std::shared_ptr<const Client>(&client);
}

int main ()
{
    Server server;
    Client client; …
Run Code Online (Sandbox Code Playgroud)

c++ pointers client-server pass-by-reference circular-reference

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

随机排列

我无法找出一种随意洗牌的方法,std::vector并在一些操作后恢复原始订单.我知道这应该是一个相当简单的算法,但我想我太累了......

由于我被限制使用自定义随机数生成器类,我想我无法使用std::random_shuffle,这无论如何都没有帮助,因为我还需要保留原始顺序.因此,我的方法是创建一个std::map用作原始位置和随机位置之间的映射,如下所示:

std::map<unsigned int, unsigned int> getRandomPermutation (const unsigned int &numberOfElements)
{
    std::map<unsigned int, unsigned int> permutation;

    //populate the map
    for (unsigned int i = 0; i < numberOfElements; i++)
    {
        permutation[i] = i;
    }

    //randomize it
    for (unsigned int i = 0; i < numberOfElements; i++)
    {
        //generate a random number in the interval [0, numberOfElements)
        unsigned long randomValue = GetRandomInteger(numberOfElements - 1U);

        //broken swap implementation
        //permutation[i] = randomValue;
        //permutation[randomValue] = i;

        //use …
Run Code Online (Sandbox Code Playgroud)

c++ random mapping algorithm permutation

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

链接对象和静态库

我很难确定执行链接时要传递给g ++的标志。基本上,我用这些“标准”标志编译一些代码:

CXXFLAGS = -Wall -Wextra -Wconversion -pedantic -std=c++0x -O2
Run Code Online (Sandbox Code Playgroud)

然后,将生成的.o文件合并到几个静态库中,如下所示:

libxxx.a: xxx1.o xxx2.o ...
    ar rcs $@ $^
libyyy.a: yyy1.o yyy2.o ...
    ar rcs $@ $^
...
Run Code Online (Sandbox Code Playgroud)

问题:

  • -static编译.o文件时,是否需要在CXXFLAGS中使用该标志?

创建静态库之后,我想将一些已编译的.o文件与这些库中的一些链接在一起,以构建可执行文件,因此我使用以下方法:

LINKER = g++
LIB_DIR = lib/linux
SYSTEM_LIBS = -lgmp
LDFLAGS = -Wall -L $(OUTPUT_DIR) -L $(LIB_DIR) $(SYSTEM_LIBS)
$(LINKER) $^ $(LDFLAGS) -lsvm -lUtils -lKinderedSpirits -o $@

exe:
    $(LINKER) o1.o o2.o $(LDFLAGS) -lxxx -lyyy -lzzz -o $@
Run Code Online (Sandbox Code Playgroud)

问题:

-我应该在-static这里使用标志吗? - -Wall在这里有意义吗?还是仅对编译有用?-是否需要将其他“标准”标志传递给链接器,类似于为编译器推荐的那些标志?

另外,在链接期间,它为我提供了有关GMP库中未定义引用的例外。据我所知,-lgmp发送到链接器并安装在系统上(我能够通过命令行使用GMP编译一个简单的hello世界),而libxxx.a libyyy.a libzzz.a是位于$(LIB_DIR)中。也许我应该提到libxxx.a中使用了GMP符号。


更新

我设法修复了GMP符号的未定义引用。问题是由我放置库的顺序引起的。基本上,按规定 …

c++ linker makefile g++ gmp

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

GCC和预编译头

在阅读了这篇精彩的文章(预编译标题的关注和喂养)之后,我对这些文章在现实生活中如何实际起作用存在疑问.更具体地说,我怎么知道在以下场景中我需要触发预编译头的重建:

  • 我决定#define在我的一个.cpp文件中改变预处理器解释已经包含在我的预编译头中的一些头的方式
  • 我在我的一个.cpp文件中包含另一个标题,该标题#define是特定的预处理器指令,它改变了预处理器解释已经包含在预编译头中的标头的方式
  • 更糟糕的是,当某些标头#include其他标头时,前一个问题可以递归发生

是否应该使用预编译的头文件强制执行某种限制性编码样式,例如将.cpp文件中包含的头文件数限制为一个并且永远不会将#define内容限制在.cpp文件中?

虽然微软的编译器可能在预先编译的头文件中做了不错的工作(通过应用一些特定于MS的voodoo),因为据我所知,它提供了应该做所有管道的选项/Yc/Yu选项,对于GCC来说,似乎这个功能需要Makefile中的大量手动工作和创造力,我无法找到应该解决使用预编译头文件的所有陷阱的模板.

例如,如果我有一个构建多个库的项目,为了在每次更改后不重建所有库,我必须在Makefile中使用一些非常可爱的sed技巧来检测#include当前库中的一个头文件是否被修改(或者它#include是一个修改过的标题).我担心甚至会想到预先构建的头文件实际上意味着的复杂性,以便构建脚本在每次必要时重建它们.

c++ dependencies gcc precompiled-headers

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

使用 CGo 调用带有双指针输出参数的 C 函数

我试图找出调用此函数的正确方法:

size_t
fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap)
{
    if (datap)
        *datap = (buf ? buf->data : NULL);
    return (buf ? buf->len : 0);
}
Run Code Online (Sandbox Code Playgroud)

使用 CGo 获取底层字符串及其长度作为 Go 中的字节数组。

这是正确的方法吗?

var bufferContents *C.uchar
length := C.fz_buffer_storage(ctx, buf, &bufferContents)
bytes := C.GoBytes(unsafe.Pointer(bufferContents), C.int(length))
Run Code Online (Sandbox Code Playgroud)

由于 C 代码覆盖了*datap,我不确定垃圾收集器是否仍然会做正确的事情。

我在这里看到一个答案暗示了一些类似的东西

var tempUcharPtr *C.uchar
bufferContents := C.malloc(C.size_t(unsafe.Sizeof(tempUcharPtr)))
defer C.free(bufferContents)
length := C.fz_buffer_storage(ctx, buf, (**C.uchar)(bufferContents))
bytes := C.GoBytes(unsafe.Pointer(*(**C.uchar)(bufferContents)), C.int(length))
Run Code Online (Sandbox Code Playgroud)

这似乎也有效,但它更复杂,我想知道它是否比以前的版本更好/更安全。

c garbage-collection pointers go cgo

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

使用std :: unique_ptr和自定义deallocator包装原始指针

我正在尝试将libsvm用于某个复杂的应用程序,因为libsvm主要是一个C库,所以在加载某些数据后,必须使用自定义API函数来释放内存.这就是我的意思:

struct svm_model *model;
model = svm_load_model("path to model file");

//do some processing

svm_free_and_destroy_model(&this->model);
Run Code Online (Sandbox Code Playgroud)

这些是我使用的libsvm API函数的定义:

struct svm_model *svm_load_model(const char *model_file_name);
void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr);
Run Code Online (Sandbox Code Playgroud)

虽然这很好用,但如果在处理模型数据时发生异常,那么我最终会遇到内存泄漏.为了防止这种情况,我将上面的代码包装在一个类中,我svm_load_model在构造函数和svm_free_and_destroy_model析构函数中调用它.

现在,由于我们处于智能指针的时代,我想要更有创意,并且,不知何故,将模型变量声明为std::unique_ptr,将指针设置svm_free_and_destroy_model为自定义解除分配器,但不幸的是,我不是能够弄清楚这样的事情是否可行.目前,我甚至无法编译,我只是在黑暗中拍摄.以下是我认为它应该如何工作:

std::unique_ptr<struct svm_model *, /* what should I add here? */ > model (svm_load_model("path to model file"), svm_free_and_destroy_model);
Run Code Online (Sandbox Code Playgroud)

c c++ pointers unique-ptr libsvm

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

链接器问题与构造函数参数的默认值

我试图为方法(或构造函数)参数的默认值强加某种语义逻辑.这是我尝试过的:

#include <iostream>
#include <vector>
class Test
{
public:
    static const std::vector<int> staticVector;
    Test (const std::vector<int> &x = Test::staticVector) {}
};

int main ()
{
    Test x;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

尽管staticVector相当冗余,但由于C++不允许将NULL作为std :: vector的实例传递,我希望避免对构造函数std :: vector()进行冗余调用,所以我提出了这种方法. .

不幸的是,当我尝试编译它时,链接器会抛出此错误:

error LNK2001: unresolved external symbol "public: static class std::vector<int,class std::allocator<int> > const Test::staticVector" (?staticVector@Test@@2V?$vector@HV?$allocator@H@std@@@std@@B)
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

c++ linker static default-value

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

根据输入参数确定返回类型

我正在尝试实现一个通用的配置文件解析器,我想知道如何在我的类中编写一个能够根据输入参数的类型确定其返回类型的方法.这就是我的意思:

class Config
{
    ...
    template <typename T>
    T GetData (const std::string &key, const T &defaultValue) const;
    ...
}
Run Code Online (Sandbox Code Playgroud)

为了调用上面的方法,我必须使用这样的东西:

some_type data = Config::GetData<some_type>("some_key", defaultValue);
Run Code Online (Sandbox Code Playgroud)

如何摆脱冗余规范?我看到boost :: property_tree :: ptree :: get()能够做到这一点,但实现相当复杂,我无法破译这个复杂的声明:

template<class Type, class Translator>
typename boost::enable_if<detail::is_translator<Translator>, Type>::type
get(const path_type &path, Translator tr) const;
Run Code Online (Sandbox Code Playgroud)

如果可能的话,我想这样做,而不会在使用我的Config类的代码中创建依赖boost.

PS:当谈到C++模板时,我是一个n00b :(

c++ templates boost return-type

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

识别Linux下共享驱动器上的文件和文件夹

我试图使用以下代码列出共享驱动器上某个目录中的所有文件:

#include <iostream>
#include <string>

#include "dirent.h"

int main ()
{
    DIR *directoryHandle = opendir("./temp/");
    if (NULL != directoryHandle)
    {
        dirent *entry = readdir(directoryHandle);
        while (NULL != entry)
        {
            //skip directories and select only files (hopefully)
            if ((DT_DIR != entry->d_type) && (DT_REG == entry->d_type || DT_UNKNOWN == entry->d_type))
            {
                std::cout << "Name: " << entry->d_name << " Type:" << std::to_string(entry->d_type) << std::endl;
            }

            //go to next entry
            entry = readdir(directoryHandle);
        }
        closedir(directoryHandle);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是entry-> d_type包含目录的DT_UNKNOWN以及目录中的./temp/文件. …

c++ linux filesystems directory dirent.h

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

将对象引用存储在一个简单的容器中

我正在寻找一种方法A在容器对象内插入多个类型的对象,而不是A在插入过程中复制每个对象.一种方法是A通过引用传递对象,但不幸的是,据我所知,STL容器只接受按插值的值传递对象(出于很多好的理由).通常情况下,这不是问题,但在我的情况下,我不希望调用复制构造函数并将原始对象销毁,因为它A是C库的包装器,其中包含一些C语言指针到内部结构,将与原始对象一起删除...

给定一个特定的索引,我只需要一个可以返回其中一个对象的容器,并存储一定数量的在运行时确定的项目,所以我想也许我可以编写自己的容器类,但我不知道如何这样做得恰到好处.

另一种方法是将指针存储A在容器内部,但由于我对这个主题没有太多的知识,在STL容器中插入指向对象的指针是什么?例如:

std::vector<A *> myVector;
for (unsigned int i = 0; i < n; ++i)
{
    A *myObj = new myObj();
    myVector.pushBack(myObj);
}
Run Code Online (Sandbox Code Playgroud)

可能有用,但我不确定如何正确处理它以及如何以干净的方式处理它.我应该完全依赖包含myVector的类的析构函数来处理它吗?如果此析构函数在删除其中一个包含的对象时抛出异常会发生什么?

此外,有些人建议使用像shared_ptrauto_ptr或类似的东西unique_ptr,但我对这么多的选择感到困惑.哪一个是我的方案的最佳选择?

c++ containers pointers stl reference

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

自动依赖生成

我正在阅读make 手册中的自动依赖项生成,但我不明白为什么需要此功能。我正在开发并从头开始编写的项目的结构如下:

  • 每个单元(图书馆)都有自己的文件夹
  • 每个 .cpp 文件应包含同一目录中具有相同名称的单个 .h 文件。好的,这个规则可能有点过于严格,就像在循环依赖的情况下一样,在这种情况下我可能会包含另一个 .h 文件,就像下一个规则中所描述的那样
  • 在 .h 文件中包含其他标头时,如果依赖项位于另一个单元(库)中,请始终使用相对于项目根目录的路径。否则,只需包含文件名。

在 makefile 中,我传递-I .给编译器。当它在目录X中遇到.cpp文件时,它会在同一目录(或目录中)中搜索.h文件.。当解析 .h 文件时,它会遇到相对于该.文件夹的包含,因此它会知道在哪里查找它们。

现在,如果代码可以像我上面描述的那样构造,为什么有人想要生成带有该标志的依赖项列表-M并使用 sed 来生成一个晦涩的 .d 文件(依赖项 fie)?我不认为从代码文件生成特定的依赖项列表有什么意义。

c++ dependencies gcc makefile compilation

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