c++ - c++ 中内联函数的零成本列表

标签 c++ c++11 stl inline overhead

我喜欢在列表上编写函数检查。为此,我通常编写如下函数:

inline bool good_strings(const std::vector<const char *> & items)
{
    for (i in items) {
        if (not is_good(i)) return false;
    }
    return true;
}

然后我可以像 if (all_good({"a", "b", "c", "d", "e"})) {...} 这样写,它看起来非常好。当您对几个项目的支票像这样变大时,这很适合使用:

if (is_good("a") and is_good("b") and /* that's too much, man */ is_good("c")) {...}

但我担心我正在使用的容器的开销,而且很难选择一个:std::vectorstd::listQListQStringList 甚至可能是 std::arraystd::initializer_list - 应该用于内联函数?在使用 {} 括号创建时,其中哪些 a 的开销最小甚至为零

好吧,更新:我捕获了我 friend 的 IDA Pro 许可并检查了一些选项。

  • std::initializer_list:该函数甚至没有内联,还有 是创建列表和复制指针的开销。
  • std::vector:函数内联,但是,有一个 创建 vector 和在那里复制指针的开销。
  • std::array:由于模板特化,不那么好看, 并且函数没有内联。所以多次调用它会创建 许多类似的代码块。但是,数组没有开销 创建,所有指针都作为函数参数传递,这 对于 x86_64 注册调用约定来说速度很快。

问题仍然存在,是否存在绝对零成本的容器

最佳答案

所有容器都不会是零开销。 std::arraystd::initializer_list会给你最少的成本。 std::array需要在编译时指定它的类型和大小,因此它不如 std::initializer_list 用户友好。在这种情况下。所以,使用 std::initializer_list<const char*>将是您可以使用的最小且最容易使用的“容器”。它将花费编译器生成的指针数组的大小,并且可能多一点,并且不需要任何动态内存分配。


如果你能使用C++17,你甚至不需要容器。使用variadic template和一个 fold expression 您可以将所有参数作为单独的参数传递给函数,并对所有参数应用相同的操作。

template<typename... Args>
bool good_strings(Args&&... args)
{
    return (is_good(args) && ...);
}

会转

all_good("a", "b", "c", "d", "e")

进入

return is_good("a") && is_good("b") && ... && is_good("e");

利用短路,所以它会在第一次调用 is_good 时立即停止评估返回 false。

您可以使用 C++11 中的可变参数模板,但您要么需要使用递归,要么构建您自己的数组,这实际上不会给您带来额外的复杂性。

关于c++ - c++ 中内联函数的零成本列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54522634/

相关文章:

c++ - 使用 Fortran 中的内存数据调用 C 代码

c++ - 如何处理线程竞速(C++;TinyThread++)?

c++ - 如果 T 是从特定基类派生的,如何专门化模板类的实现

c++ - `std::string::iterator` 保证不是指向 char 的指针吗?

c++ - 寻找提供随机访问和 "sequential"访问的数据结构

c++ - 处理 utf-8 字符串 gtk

C++ 结构数据成员

c++ - QAbstractButton 的 SIGNAL SLOT 新符号的问题

c++ - std::to_string is not returned 在 aix 中声明编译错误

c++ - 使用可变参数模板以更多参数概括 STL 算法