I think it is best to use const char (&s)[N] (with template<size_t N> ) as the parameter type. But it also binds to any const char array other than a string literal.
Add the created array constructor without the char constructor to prevent it from being called using a non-constant array.
class LitRf { const char* data_; Sz size_; public: template<size_t N> LitRf(char const (&s)[N]) : data_{s}, size_{N} {} template<size_t N> LitRf(char (&s)[N]) = delete; };
In addition, you can use the macro shell, which (when the constructor is never used without it) makes it possible only to create an object from a literal, even with a variable.
#define MakeLitRf(s) LitRf(s "")
The idea is to combine two string literals, the second of which is an empty string. This is only possible if the first is also a string literal; when setting a variable, a syntax error occurs. After macro expansion, the compiler sees something like LitRf("foo" "") , which is equivalent to LitRf("foo") . Some examples:
auto x = MakeLitRf("foo"); // works const char *foo = "foo"; auto x = MakeLitRf(foo); // fails auto x = LitRf(foo); // works, but we want it to fail...
In the latter case, the user inadvertently (or intentionally?) Did not use the macro, making our work useless. To make it crash, add a hidden parameter to the constructor, which you need to add when called directly (and in the macro definition, of course):
class LitRf { const char* data_; Sz size_; public:
leemes
source share