小编dma*_*ola的帖子

C++ rapidjson:GenericValue :: IsNull在任何情况下都返回false

在我们的项目中发现了一个神秘的问题后,我仍感到震惊.

我们意识到调用HasMember("string")正在进行额外搜索.因此,出于性能原因,我们会对其进行更改.

主要想法是:

而不是调用HasMember,然后预先缓存参考,如:

rapidjson::Document d;
d.Parse<0>(json);

if(d.HasMember("foo"))
{
    const rapidjson::Value& fooValue = d["foo"];

    // do something with fooValue
}
Run Code Online (Sandbox Code Playgroud)

变成:

rapidjson::Document d;
d.Parse<0>(json);

const rapidjson::Value& fooValue = d["foo"];
if( !fooValue.IsNull() )
{
    // do something with fooValue
}
Run Code Online (Sandbox Code Playgroud)

这非常好,我们保存以执行两次搜索,而不是只执行一次.但是,这就是问题所在.

如果您开始查看rapidjson如何实现nullvalue(在查找失败时默认返回),您将看到以下代码:

//! Get the value associated with the object's name.
GenericValue & operator[](const Ch* name) {
    // Check
    if (Member * member = FindMember(name)) {
        return member->value;
    } else {
        // Nothing
        static GenericValue NullValue;
        return NullValue;
    }
}

// …
Run Code Online (Sandbox Code Playgroud)

c++ performance design-patterns rapidjson

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

使用字符串作为模板参数时的编译意外

我正在玩模板中的字符串。我阅读了一些有趣的博客并开始玩代码。

在下一个示例中,我能够在模板参数中传递字符串文字:

#include <algorithm>
#include <iostream>

template<size_t N>
struct StringLiteral {
    constexpr StringLiteral(const char (&str)[N]) {
        // commenting this makes the program to not compile
        std::copy_n(str, N, value);
    }
    constexpr size_t size() const
    {
        return N;
    }

    // changing N to literal, such as 10, makes the program to not compile
    char value[N];
};

template<StringLiteral lit>
void Print() {
    static constexpr auto size = lit.size();
    static constexpr auto contents = lit.value;

    std::cout << "Size: " << size << ", Contents: …
Run Code Online (Sandbox Code Playgroud)

c++ c++20

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

为什么在模板方法中的clang中检测到不完整的类型?

今天,我在clang中遇到了一个让我感到惊讶的编译问题.我想是合理的,但我喜欢深入挖掘并听到更多细节.如果可能,还有一些标准参考.

我有一个带有模板方法的类,它依赖于一个成员,它的类型在头文件中未定义(但不在源代码中).类似于以下内容:

// Menu.h
class Page;

class Menu
{
public:
    .... // stuff

template<class Visitor>
void VisitWidget( Visitor&& visitor);

private:
std::unique_ptr<Page> m_page; // destructor implemented in source file, so Page is an incomplete type
};

template<class Visitor>
inline void Menu::VisitWidget( Visitor&& visitor);
{
    m_page->Visit( std::forward<Visitor>(visitor) );
}
Run Code Online (Sandbox Code Playgroud)

在VisualStudio中,它编译.我希望这只会在实施时抱怨; 如此内联.但是,在clang中,只要有人包含标题,就不会编译.强迫我在Menu.h中包含Page.h(我想不惜一切代价避免使用它).

喜欢:

// Another.cpp (not Menu.cpp)
#include "Menu.h" // this trigger and error due Page is an incomplete type
Run Code Online (Sandbox Code Playgroud)

即使整个Another.cpp没有使用VisitWidget(即使在其他标题中)

我猜这是由内联引起的某种方式,因为编译器没有义务真正使用它,但由于中间有模板,我不太确定.是真的铿锵检查类型?

c++ templates smart-pointers clang c++11

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