字符串文字引用类

PSk*_*cik 7 c++ c++14

C++1y,我可以绑定到一个字符串而不是引用类char*char[]&或类似的?

class LitRf{
  const char* data_;
  size_t size_;
public:
  LitRf(const char* /*?*/ s) : data_{s},size_{sizeof(s)} { /*?*/ }
};
Run Code Online (Sandbox Code Playgroud)

lee*_*mes 3

我想你能做的最好的事情就是使用const char (&s)[N](with template<size_t N>) 作为参数类型。但它也绑定到除字符串文字之外的任何 const char 数组。

添加删除的非常量字符数组构造函数以禁止使用非常量数组调用它。

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;
};
Run Code Online (Sandbox Code Playgroud)

除此之外,您可以使用宏包装器,它(当构造函数在没有它的情况下永远不会使用时)使得只能从文字构造对象,甚至不能通过变量构造对象。

#define MakeLitRf(s) LitRf(s "")
Run Code Online (Sandbox Code Playgroud)

这个想法是连接两个字符串文字,其中第二个只是一个空字符串。仅当第一个也是字符串文字时,这才有可能;将变量放入其中会出现语法错误。宏展开后,编译器会看到类似于 的内容,LitRf("foo" "")相当于LitRf("foo"). 一些例子:

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...
Run Code Online (Sandbox Code Playgroud)

在最后一种情况下,用户无意(或有意?)没有使用宏,使我们的工作毫无价值。为了让它也失败,请向构造函数添加一个隐藏参数,直接调用时需要添加该参数(当然,在宏的定义中):

class LitRf
{
    const char* data_;
    Sz size_;
public:
    // Called by the macro MakeLitRf. Unlikely to be called directly unless the user knows what he's doing.
    LitRf(const char *s, void *)
        : data_{s}, size_{N}
    {}

    // Called without macro! Throw a compiler error, explaining what's wrong.
    LitRf(const char *s)
    {
        static_assert(false, "Please use the macro `MakeLitRf` with a string literal to construct a `LitRf`.");
    }
};

#define MakeLitRf(s) LitRf(s "", nullptr)
Run Code Online (Sandbox Code Playgroud)