Considere la siguiente función en línea:
// 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]));
}
y la versión equivalente 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]));
}
Mi pregunta es: ¿el constexprespecificador implica el inlineespecificador en el sentido de que si se pasa un argumento no constante a una constexprfunción, el compilador intentará inlinela función como si el inlineespecificador se pusiera en su declaración?
¿El estándar C ++ 11 garantiza eso?

inlineespecificador. (O tal vez entendí mal tu fraseo.)inlineespecificador ya no tiene nada que ver con el inlininginlineestá directamente relacionada con el inlining. Entonces no, elconstexprespecificador no implica elinlineespecificador en ese sentido, ya que ese sentido no existe.Respuestas:
Sí ([dcl.constexpr], §7.1.5 / 2 en el estándar C ++ 11): "las funciones constexpr y los constructores constexpr están implícitamente en línea (7.1.2)".
Sin embargo,
inlinetenga en cuenta que el especificador realmente tiene muy poco efecto (si es que tiene alguno) sobre si es probable que un compilador expanda una función en línea o no. Sin embargo, sí afecta la regla de una definición, y desde esa perspectiva, el compilador debe seguir las mismas reglas para unaconstexprfunción comoinlinefunción.También debo agregar que independientemente de
constexprlo que implicainline, las reglas paraconstexprfunciones en C ++ 11 requerían que fueran lo suficientemente simples como para que a menudo fueran buenos candidatos para la expansión en línea (la excepción principal son las que son recursivas). Desde entonces, sin embargo, las reglas se han vuelto progresivamente más flexibles, por lo queconstexprpueden aplicarse a funciones sustancialmente más grandes y complejas.fuente
constexprfunciones no causarán generación de código en absoluto ...constexprfunciones de @KerrekSB se evalúan potencialmente en tiempo de compilación. Sin embargo, el estándar C ++ 14 está plagado de algunos que muy probablemente se llamarán en tiempo de ejecución. Por ejemplo:std::array<T,N>::atconstexprno implicainlinepara variables no estáticas (variables en línea de C ++ 17)Si bien
constexprimplicainlinepara funciones, no tiene ese efecto para variables no estáticas, considerando las variables en línea de C ++ 17.Por ejemplo, si toma el ejemplo mínimo que publiqué en: ¿Cómo funcionan las variables en línea? y elimine el
inline, dejando soloconstexpr, entonces la variable obtiene múltiples direcciones, que es lo principal que evitan las variables en línea.constexprSin embargo, las variables estáticas son implícitamente estáticas.Ejemplo mínimo que
constexprimplicainlinepara funcionesComo se menciona en: https://stackoverflow.com/a/14391320/895245, el efecto principal de
inlineno es inline sino permitir múltiples definiciones de una función, cita estándar en: ¿Cómo puede un archivo de encabezado C ++ incluir la implementación?Podemos observar eso jugando con el siguiente ejemplo:
main.cpp
notmain.hpp
notmain.cpp
Compilar y ejecutar:
Si eliminamos
inlinedeshared_func, el enlace fallaría con:porque el encabezado se incluye en varios
.cpparchivos.Pero si reemplazamos
inlineconconstexpr, entonces funciona de nuevo, porqueconstexprtambién implicainline.GCC implementa eso al marcar los símbolos como débiles en los archivos de objeto ELF: ¿Cómo puede un archivo de encabezado C ++ incluir la implementación?
Probado en GCC 8.3.0.
fuente
constexprtodavía está en línea. cppreference.com : una variable miembro estática (pero no una variable de ámbito de espacio de nombres) declaradaconstexpres implícitamente una variable en línea.