Rozważ następującą wbudowaną funkcję:
// 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]));
}
i odpowiednik w wersji 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]));
}
Moje pytanie brzmi: czy constexpr
specyfikator implikuje inline
specyfikator w tym sensie, że jeśli do constexpr
funkcji zostanie przekazany argument inny niż stały , kompilator spróbuje inline
tej funkcji tak, jakby inline
specyfikator został umieszczony w jej deklaracji?
Czy standard C ++ 11 to gwarantuje?
inline
robi specyfikator. (A może źle zrozumiałem twoje sformułowanie.)inline
nie ma już nic wspólnego z inliningieminline
jest bezpośrednio związane z inliningiem. Więc nie,constexpr
specyfikator nie implikujeinline
specyfikatora w tym sensie, ponieważ ten sens nie istnieje.Odpowiedzi:
Tak ([dcl.constexpr], §7.1.5 / 2 w standardzie C ++ 11): „funkcje constexpr i konstruktory constexpr są niejawnie wbudowane (7.1.2)”.
Należy jednak zauważyć, że
inline
specyfikator naprawdę ma bardzo niewielki (jeśli w ogóle) wpływ na to, czy kompilator prawdopodobnie rozszerzy funkcję wbudowaną, czy nie. Ma to jednak wpływ na regułę jednej definicji iz tej perspektywy kompilator musi przestrzegać tych samych reguł dlaconstexpr
funkcji, coinline
funkcja.Powinienem również dodać, że niezależnie od
constexpr
implikacjiinline
, reguły dlaconstexpr
funkcji w C ++ 11 wymagały, aby były na tyle proste, że często były dobrymi kandydatami do rozwijania inline (podstawowym wyjątkiem są te, które są rekurencyjne). Jednak od tego czasu reguły stawały się coraz luźniejsze, więcconstexpr
można je zastosować do znacznie większych, bardziej złożonych funkcji.źródło
constexpr
funkcji w ogóle nie spowoduje generowania kodu ...constexpr
Funkcje @KerrekSB są potencjalnie oceniane w czasie kompilacji. Jednak standard C ++ 14 jest zaśmiecony tymi, które najprawdopodobniej będą wywoływane w czasie wykonywania. Na przykład:std::array<T,N>::at
constexpr
nie oznaczainline
zmiennych niestatycznych (zmienne wbudowane w C ++ 17)Chociaż
constexpr
sugeruje toinline
dla funkcji, nie ma tego efektu w przypadku zmiennych niestatycznych, biorąc pod uwagę zmienne wbudowane w C ++ 17.Na przykład, jeśli weźmiesz minimalny przykład, który opublikowałem pod adresem: Jak działają zmienne wbudowane? i usuń
inline
, pozostawiając po prostuconstexpr
, wtedy zmienna otrzymuje wiele adresów, co jest główną rzeczą, której zmienne wbudowane unikają.constexpr
zmienne statyczne są jednak niejawnie statyczne.Minimalny przykład, który
constexpr
sugerujeinline
dla funkcjiJak wspomniano na: https://stackoverflow.com/a/14391320/895245, głównym efektem
inline
nie jest wstawianie, ale dopuszczenie wielu definicji funkcji, standardowy cytat pod adresem: W jaki sposób plik nagłówkowy C ++ może zawierać implementację?Możemy to zaobserwować, grając na poniższym przykładzie:
main.cpp
notmain.hpp
notmain.cpp
Skompiluj i uruchom:
Jeśli usuniemy
inline
zshared_func
, link nie zadziała z:ponieważ nagłówek jest dołączany do wielu
.cpp
plików.Ale jeśli zastąpimy
inline
goconstexpr
, to znowu działa, ponieważconstexpr
również implikujeinline
.GCC implementuje to, oznaczając symbole jako słabe w plikach obiektowych ELF: W jaki sposób plik nagłówkowy C ++ może zawierać implementację?
Przetestowano w GCC 8.3.0.
źródło
constexpr
jest nadal wbudowana. cppreference.com : zadeklarowana statyczna zmiennaconstexpr