字符串文字引用类

时间:2016-03-03 12:29:57

标签: 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)} { /*?*/ }
};

3 个答案:

答案 0 :(得分:3)

C ++ 11删除了检测字符串文字的唯一正式方法,即通过隐式转换为指向非const的指针。

无论如何使用小技巧必须使用宏。

在C ++ 11及更高版本中,您可以做的最好的事情是建立一个强大的约定, const字符类型的数组是一个文字。

即,用你的例子,

class LitRf
{
private:
    const char* data_;
    Sz size_;

    template< size_t n >
    LitRf( char (&)[n] ) = delete;

public:
    template< size_t n >
    LitRf( char const (&s)[n] )
        : data_{s}, size_{sizeof(s) - 1}
    {}
};

请注意使用size_t而不是可能签名的类型Sz。这确保代码将使用g ++进行编译。不幸的是,编译器或它的旧版本有一个错误,它在size_t上非常坚持,否则它拒绝接受代码。

答案 1 :(得分:3)

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

添加一个已删除的非const char数组构造函数,禁止使用非const数组调用它。

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;
};

除此之外,你可以使用一个宏包装器(当没有它时从不使用构造函数时)使得它只能从文字构造一个对象,甚至不能通过一个变量。

#define MakeLitRf(s) LitRf(s "")

这个想法是连接两个字符串文字,其中第二个只是一个空字符串。只有当第一个也是字符串文字时才可以这样做;放置一个变量有一个语法错误。在宏扩展之后,编译器会看到类似于LitRf("foo" "")的{​​{1}}。一些例子:

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...

答案 2 :(得分:1)

<div class="row gallery">
    <div class="col-md-3">
        <a href="photo.jpg" data-gallery="gallery">
            <img src="photo.jpg" class="img-responsive" />
        </a>
    </div>
    . . . 
</div>