我喜欢在列表上编写函数检查。为此,我通常编写如下函数:
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::vector
、std::list
、QList
、QStringList
甚至可能是 std::array
或 std::initializer_list
- 应该用于内联函数?在使用 {}
括号创建时,其中哪些 a 的开销最小甚至为零?
好吧,更新:我捕获了我 friend 的 IDA Pro 许可并检查了一些选项。
std::initializer_list
:该函数甚至没有内联,还有 是创建列表和复制指针的开销。std::vector
:函数内联,但是,有一个 创建 vector 和在那里复制指针的开销。std::array
:由于模板特化,不那么好看, 并且函数没有内联。所以多次调用它会创建 许多类似的代码块。但是,数组没有开销 创建,所有指针都作为函数参数传递,这 对于x86_64
注册调用约定来说速度很快。
问题仍然存在,是否存在绝对零成本的容器?
最佳答案
所有容器都不会是零开销。 std::array
或 std::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/