bimo
¿Es posible en “C++ moderno” (C++17 o superior) pasar un literal de cadena como parámetro a una plantilla de C++?
Me doy cuenta de que podrías hacer esto con el argumento del constructor; Simplemente pensé que sería más conveniente tenerlo como un argumento de plantilla, en lugar de estar enterrado en lo profundo del archivo cpp. Tenía curiosidad por saber si tal vez esta era una característica nueva del C++ moderno. Vea el pseudocódigo a continuación de lo que estoy tratando de hacer:
Ejemplo de pseudocódigo:
// Header File /////////////////////////
template<constexpr string Name>
class ModuleBase {
public:
ModuleBase();
string name;
};
class xyz : ModuleBase<"xyz"> {
public:
xyz();
};
// Cpp File //////////////////////////
template<string_literal Name>
ModuleBase<Name>::ModuleBase() {
name = Name;
}
xyz::xyz() : ModuleBase() {
}
Yakk – Adam Nevraumont
Sí, en c++20.
El problema era que era difícil determinar la unicidad de un argumento sin tipo de plantilla.
c++20 agrega en un <=>
Comparación de operadores de naves espaciales. Si no es proporcionado por el usuario (y se basa solo en datos no proporcionados por el usuario) <=>
a su vez, repetir recursivamente) (y un algunos otros requisitos; ver p0732), el tipo se puede usar como un argumento de plantilla que no es de tipo.
Estos tipos se pueden construir a partir de materias primas "strings"
en constexpr
constructores, incluido el uso de guías de deducción de C++ 17 para que se autodimensionen.
Como el tamaño de los datos almacenados probablemente formará parte del tipo, querrá tomar el tipo como un auto
parámetro sin tipo escrito o tipo deducido automáticamente.
Tenga en cuenta que colocar la implementación de su plantilla en un archivo cpp suele ser una mala idea. Pero esa es otra pregunta.
-
Esto fue aceptado en EWG, pero AFAIK, todavía tiene que pasar por CWG antes de que esté realmente en C ++ 20 (con las advertencias habituales de que C ++ 20 no se realiza hasta que se realiza). Sin embargo, parece probable.
– chris
5 de julio de 2018 a las 16:09
-
Estoy irrazonablemente feliz de que
<=>
es ampliamente conocido como “el operador de la nave espacial”.– Ti Strga
5 de julio de 2018 a las 19:25
-
@TiStrga Fue nombrado así incluso en el documento introductorio: open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0515r0.pdf banco banco
– Yakk – Adam Nevraumont
5 de julio de 2018 a las 19:40
-
@chris Está desactualizado, fue aprobado por CWG y el plenario lo votó 🙂
– Rakete1111
5 de julio de 2018 a las 22:37
-
@ Rakete1111 ¿No? “tiene un operador no proporcionado por el usuario que devuelve un tipo que se puede convertir implícitamente a std::strong_equality y no contiene referencias”. — el requisito es más fuerte que
constexpr
no es proporcionada por el usuario recursivamente (que esconstexpr
)– Yakk – Adam Nevraumont
6 de julio de 2018 a las 13:14
Hasta que obtenga c ++ 20 y si tiene impulso, puede encontrar útil la siguiente macro:
#define C_STR(str_) boost::mpl::c_str< BOOST_METAPARSE_STRING(str_) >::value
Luego usa lo siguiente:
template<const char* str>
structe testit{
};
testit<C_STR("hello")> ti;
FWIW, no puede poner las definiciones de una clase de plantilla en un archivo cpp: stackoverflow.com/questions/495021/…
– NathanOliver
5 de julio de 2018 a las 15:48
@NathanOliver puedes, con largas advertencias
– Caleth
5 de julio de 2018 a las 15:50
Sí, lo sé, pero es mucho más fácil dejar que el OP lea la explicación real y luego tratar de resumirlo todo en un comentario.
– NathanOliver
5 de julio de 2018 a las 15:51
@BillMoore El problema no es la sintaxis, el problema es la semántica: la plantilla definición (¡no solo la declaración!) debe estar visible en el lado del uso, por lo que básicamente tendría que usarlo como un encabezado de todos modos (o solo usarlo localmente).
– Cúbico
5 de julio de 2018 a las 15:54
stackoverflow.com/questions/1826464/…
– norte 1.8e9-dónde-está-mi-participación m.
5 de julio de 2018 a las 15:59