在C++1y
中,我是否可以拥有一个与字符串文字绑定但不与char*
或char[]&
或类似字符绑定的引用类?
class LitRf{
const char* data_;
size_t size_;
public:
LitRf(const char* /*?*/ s) : data_{s},size_{sizeof(s)} { /*?*/ }
};
答案 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>