132

次のインライン関数について考えてみます。

// Inline specifier version
#include<iostream>
#include<cstdlib>

inline int f(const int x);

inline int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}

およびconstexprと同等のバージョン:

// Constexpr specifier version
#include<iostream>
#include<cstdlib>

constexpr int f(const int x);

constexpr int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}

私の質問は:指定子は、定数でない引数が関数に渡された場合、コンパイラーは指定子が宣言に入れられたかのように関数を試行するという意味で指定子をconstexpr意味しますか?inlineconstexprinlineinline

C ++ 11標準はそれを保証しますか?

4

2 に答える 2

160

はい([dcl.constexpr]、C ++11標準の§7.1.5/2):「constexpr関数とconstexprコンストラクターは暗黙的にインライン(7.1.2)です。」

ただし、inline指定子は、コンパイラーが関数をインラインで展開する可能性があるかどうかにほとんど影響を与えないことに注意してください。ただし、これは1つの定義規則に影響します。その観点から、コンパイラーは関数に対してconstexpr関数と同じ規則に従う必要がありinlineます。

constexprまた、暗黙に関係なく、C ++ 11の関数inlineのルールではconstexpr、インライン展開の候補として適していることが多いほど単純である必要がありました(主な例外は再帰的なものです)。ただし、それ以降、ルールは徐々に緩くなり、constexpr大幅に大きく、より複雑な関数に適用できるようになりました。

于 2013-01-18T01:55:20.347 に答える
47

constexprinline非静的変数(C ++ 17インライン変数)を意味するものではありません

は関数をconstexpr意味inlineしますが、C ++ 17インライン変数を考慮すると、非静的変数にはその効果はありません。

たとえば、私が投稿した最小限の例をとると、インライン変数はどのように機能しますか?を削除しinline、そのままにしておくとconstexpr、変数は複数のアドレスを取得します。これは、インライン変数が回避する主なことです。

constexprただし、静的変数は暗黙的にインラインです。

関数をconstexpr暗示する最小限の例inline

https://stackoverflow.com/a/14391320/895245で述べたように、の主な効果はinlineインラインではなく、関数の複数の定義を許可することです。標準引用符:C ++ヘッダーファイルに実装を含めるにはどうすればよいですか?

次の例で遊ぶことで、それを観察できます。

main.cpp

#include <cassert>

#include "notmain.hpp"

int main() {
    assert(shared_func() == notmain_func());
}

notmain.hpp

#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP

inline int shared_func() { return 42; }
int notmain_func();

#endif

notmain.cpp

#include "notmain.hpp"

int notmain_func() {
    return shared_func();
}

コンパイルして実行します。

g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'notmain.o' 'notmain.cpp' 
g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.o' 'main.cpp' 
g++ -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.out' notmain.o main.o
./main.out

inlineから削除するとshared_func、リンクは次のように失敗します。

multiple definition of `shared_func()'

ヘッダーが複数の.cppファイルに含まれるためです。

しかし、に置き換えるinlineと、も意味するconstexprので、再び機能します。constexprinline

GCCは、ELFオブジェクトファイルでシンボルを弱いものとしてマークすることにより、これを実装します。C ++ヘッダーファイルに実装を含めるにはどうすればよいですか?

GCC8.3.0でテスト済み。

于 2019-08-08T07:48:19.330 に答える