Рассмотрим следующую встроенную функцию:
// 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
подразумевает ли inline
спецификатор спецификатор в том смысле, что если в constexpr
функцию передается непостоянный аргумент , компилятор попытается выполнить inline
эту функцию, как если бы inline
спецификатор был помещен в ее объявление?
Гарантирует ли это стандарт C ++ 11?
inline
делает спецификатор. (Или, может быть, я неправильно понял вашу формулировку.)inline
больше не имеет ничего общего с встраиваниемinline
которое напрямую связано с встраиванием. Итак, нет,constexpr
спецификатор не подразумеваетinline
спецификатор в этом смысле, поскольку этого смысла не существует.Ответы:
Да ([dcl.constexpr], §7.1.5 / 2 в стандарте C ++ 11): «функции constexpr и конструкторы constexpr неявно встроены (7.1.2)».
Обратите внимание, однако, что
inline
спецификатор действительно очень мало (если он вообще есть) влияет на то, будет ли компилятор расширять встроенную функцию или нет. Однако это влияет на одно правило определения, и с этой точки зрения компилятор должен следовать тем же правилам дляconstexpr
функции, что и дляinline
функции.Я также должен добавить, что независимо от того, что
constexpr
подразумеваетсяinline
, правила дляconstexpr
функций в C ++ 11 требовали, чтобы они были достаточно простыми, чтобы они часто были хорошими кандидатами для встроенного расширения (основным исключением были те, которые являются рекурсивными). Однако с тех пор правила становятся все более свободными, поэтомуconstexpr
их можно применять к значительно более крупным и сложным функциям.источник
constexpr
функций вообще не вызовет генерации кода ...constexpr
Функции @KerrekSB потенциально оцениваются во время компиляции. Однако стандарт C ++ 14 изобилует стандартами, которые, скорее всего, будут вызываться во время выполнения. Например:std::array<T,N>::at
constexpr
не подразумеваетinline
для нестатических переменных (встроенные переменные C ++ 17)Хотя
constexpr
это и подразумеваетсяinline
для функций, он не имеет такого эффекта для нестатических переменных, учитывая встроенные переменные C ++ 17.Например, возьмем минимальный пример, который я разместил по адресу: Как работают встроенные переменные? и удалите
inline
, оставив толькоconstexpr
, тогда переменная получит несколько адресов, чего в основном избегают встроенные переменные.constexpr
однако статические переменные неявно статичны.Минимальный пример, который
constexpr
подразумеваетinline
для функцийКак упоминалось по адресу: https://stackoverflow.com/a/14391320/895245, основной эффект
inline
заключается не во встроении, а в разрешении нескольких определений функции, стандартная цитата по адресу: Как файл заголовка C ++ может включать реализацию?Мы можем убедиться в этом, поиграв со следующим примером:
main.cpp
notmain.hpp
notmain.cpp
Скомпилируйте и запустите:
Если мы удалим
inline
изshared_func
, ссылка не удастся:потому что заголовок включается в несколько
.cpp
файлов.Но если мы заменим
inline
наconstexpr
, то он снова работает, потому чтоconstexpr
также подразумеваетinline
.GCC реализует это, помечая символы как слабые в объектных файлах ELF: Каким образом файл заголовка C ++ может включать реализацию?
Протестировано в GCC 8.3.0.
источник
constexpr
все еще встроена. cppreference.com : объявленная статическая переменная-член (но не переменная области пространства имен)constexpr
неявно является встроенной переменной.