Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible in modern C++ to pass a string literal as a parameter to a C++ template?

Tags:

c++

c++17

c++20

Is it possible in "modern C++" (C++17 or greater) to pass a string literal as a parameter to a C++ template?

I realize you could do this with constructor argument; I just thought it would be more convenient to have it as a template argument, rather than buried deep in the cpp file. I was curious if maybe this was a new feature of modern C++. See Pseudo code below of what I'm trying to do:

Pseudo-code Example:

// 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() {  } 
like image 365
Bimo Avatar asked Jul 05 '18 15:07

Bimo


People also ask

Can function template work with string?

A string literal cannot be used as a template argument.

Is it possible to modify a string literal in C?

Attempting to modify the string literal has undefined behavior. However, modifying a mutable array of char directly, or through a pointer is naturally not undefined behavior, even if its initializer is a literal string.

Can a string be a literal?

A string literal or anonymous string is a string value in the source code of a computer program. In modern programming languages usually use a quoted sequence of characters, formally "bracketed delimiters", as in x = "foo" . Where "foo" is a string literal with value foo .

Is string literal in C?

A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string.


2 Answers

Yes, in c++20.

The problem was that determining uniqueness of a template non-type argument was difficult.

c++20 adds in a <=> spaceship operator comparison. If it is non-user provided (and based only off non-user provided <=> in turn, repeat recursively) (and a few other requirements; see p0732), the type can be used as a non-type template argument.

Such types can be constructed from raw "strings" in constexpr constructors, including using c++17 deduction guides to make them auto-size themselves.

As the size of the data stored is probably going to be part of the type, you'll want to take the type as an auto typed non-type parameter or otherwise auto-deduced type.


Note that placing the implementation of your template in a cpp file is usually a bad idea. But that is another question.

like image 108
Yakk - Adam Nevraumont Avatar answered Sep 18 '22 18:09

Yakk - Adam Nevraumont


Until you get c++20 and if you have boost, you may find the following macro usefull:

#define C_STR(str_) boost::mpl::c_str< BOOST_METAPARSE_STRING(str_) >::value 

Then use as follows:

template<const char* str> structe testit{ }; testit<C_STR("hello")> ti; 
like image 45
darune Avatar answered Sep 21 '22 18:09

darune