简体   繁体   English

我应该内联命名空间 scope lambdas 吗? 无论哪种情况,为什么?

[英]Should I inline namespace scope lambdas? In either case, why?

Sometimes I have some capture-less lambda defined at the top of a header file, which is used in the following part of the header:有时我在 header 文件的顶部定义了一些无捕获的 lambda,该文件用于 header 的以下部分:

//#include statements
namespace detail {
auto constexpr lambda = [](/* args */){ /* body */ };
}
// in some function or whatever, use `lambda`

Often I'm told in during code reviews that I should put not only constexpr specifier, as I do, but also the inline specifier.在代码审查期间,我经常被告知我不仅应该像我一样放置constexpr说明符,还应该放入inline说明符。

Why should I do that?我为什么要那么做? What are the advantages?有什么优势?

I've tried reading inline specifier on cppreference , but I think I lack to much terminology to understand it at the moment.我已经尝试在 cppreference 上阅读inline说明符,但我认为目前我缺乏很多术语来理解它。

You should be using inline if the variable is defined in a header file.如果变量在 header 文件中定义,则应该使用inline If it is not inline, then every translation unit that includes the header file will get that definition.如果它不是内联的,那么每个包含 header 文件的翻译单元都将获得该定义。 That means you have multiple definitions for a single name which is an ODR ( One Definition Rule ) violation.这意味着您对单个名称有多个定义,这违反了 ODR(一个定义规则)。 Those do not require any diagnostics, so they can lead to hard to find bugs.这些不需要任何诊断,因此它们可能导致难以发现错误。

By making the variable inline, you fix the problem by telling the compiler/linker that it can throw out all of the duplicated definitions and just use a single one.通过使变量内联,您可以通过告诉编译器/链接器它可以丢弃所有重复的定义而只使用一个来解决问题。

According to the C++ 17 Standard (10.1.5 The constexpr specifier)根据 C++ 17 标准(10.1.5 constexpr 说明符)

1 The constexpr specifier shall be applied only to the definition of a variable or variable template or the declaration of a function or function template. 1 constexpr 说明符仅适用于变量或变量模板的定义或 function 或 function 模板的声明。 A function or static data member declared with the constexpr specifier is implicitly an inline function or variable (10.1.6).使用 constexpr 说明符声明的 function 或 static 数据成员隐式是内联 function 或变量 (10.1.6) If any declaration of a function or function template has a constexpr specifier, then all its declarations shall contain the constexpr specifier.如果 function 或 function 模板的任何声明具有 constexpr 说明符,则其所有声明都应包含 constexpr 说明符。

In the code snippet in your question the variable lambda is not a static data member.在您问题的代码片段中,变量lambda不是 static 数据成员。

namespace detail {
auto constexpr lambda = [](/* args */){ /* body */ };
}

So if the namespace detail has external linkage then and the variable lambda also has the external linkage.因此,如果命名空间detail具有外部链接,那么变量lambda也具有外部链接。 In this case if the header will be included in several compilation units then the one definition rule will be broken.在这种情况下,如果 header 将包含在几个编译单元中,则将破坏一个定义规则。 To avoid such a situation you should declare the variable as an inline variable.为避免这种情况,您应该将该变量声明为内联变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM