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

C++C++17C++20

C++ Problem Overview


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() {

}

C++ Solutions


Solution 1 - C++

Yes, in [tag:C++20].

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

[tag: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 [tag: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.

Solution 2 - C++

Until you get [tag:c++20] and if you have [tag: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;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBimoView Question on Stackoverflow
Solution 1 - C++Yakk - Adam NevraumontView Answer on Stackoverflow
Solution 2 - C++daruneView Answer on Stackoverflow