如何禁止调用 C++ 中右值对象的 const 成员函数? 2011年?
下面的代码
#include <vector>
#include <string>
#include <iostream>
std::string const& at(std::vector<std::string> const& n, int i)
{
return n[i];
}
std::vector<std::string> mkvec()
{
std::vector<std::string> n;
n.push_back("kagami");
n.push_back("misao");
return n;
}
int main()
{
std::string const& s = at(mkvec(), 0);
std::cout << s << std::endl; // D'oh!
return 0;
}
可能会导致崩溃,因为原始向量已经被破坏了。在 C++ 2011 (c++0x) 中引入右值引用后,如果向量参数是rvalue
std::string const& at(std::vector<std::string>&&, int) = delete;
看起来不错,但是下面的代码仍然会导致崩溃
int main()
{
std::string const& s = mkvec()[0];
std::cout << s << std::endl; // D'oh!
return 0;
}
,因为仍然允许调用右值对象的成员函数operator [] (size_type) const 。有什么办法可以禁止此类呼叫吗?
FIX:
上面的例子不是我在实际项目中所做的。我只是想知道 C++ 2011 是否支持任何像
class A {
void func() rvalue; // Then a call on an rvalue object goes to this overload
void func() const;
};
FIX 这样的成员函数限定:
这很棒,但我认为 C++ 标准在这个功能上走得太远了。无论如何,我在 clang++ 2.9 上编译了以下代码,
#include <cstdio>
struct A {
A() {}
void func() &
{
puts("a");
}
void func() &&
{
puts("b");
}
void func() const &
{
puts("c");
}
};
int main()
{
A().func();
A a;
a.func();
A const b;
b.func();
return 0;
}
非常感谢!
The following code
#include <vector>
#include <string>
#include <iostream>
std::string const& at(std::vector<std::string> const& n, int i)
{
return n[i];
}
std::vector<std::string> mkvec()
{
std::vector<std::string> n;
n.push_back("kagami");
n.push_back("misao");
return n;
}
int main()
{
std::string const& s = at(mkvec(), 0);
std::cout << s << std::endl; // D'oh!
return 0;
}
may lead to crash because the original vector is already destructed there. In C++ 2011 (c++0x) after rvalue-reference is introduced in, a deleted function declaration can be used to completely forbid calls to at
if the vector argument is an rvalue
std::string const& at(std::vector<std::string>&&, int) = delete;
That looks good, but the following code still cause crash
int main()
{
std::string const& s = mkvec()[0];
std::cout << s << std::endl; // D'oh!
return 0;
}
because calls to member function operator [] (size_type) const
of an rvalue object is still allowed. Is there any way can I forbid this kind of calls?
FIX:
The examples above is not what I did in real projects. I just wonder if C++ 2011 support any member function qualifying like
class A {
void func() rvalue; // Then a call on an rvalue object goes to this overload
void func() const;
};
FIX:
It's great, but I think C++ standard goes too far at this feature. Anyway, I have following code compiled on clang++ 2.9
#include <cstdio>
struct A {
A() {}
void func() &
{
puts("a");
}
void func() &&
{
puts("b");
}
void func() const &
{
puts("c");
}
};
int main()
{
A().func();
A a;
a.func();
A const b;
b.func();
return 0;
}
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,你不应该。我该怎么做
std::cout << at(mkvec(), 0) << std::endl;
,这是一个完全合理的事情,如果你禁止我在临时变量上使用at()
?不幸的是,存储对临时变量的引用只是 C++ 程序员必须处理的一个问题。
要回答您的新问题,是的,您可以这样做:
No, and you shouldn't. How am I to do
std::cout << at(mkvec(), 0) << std::endl;
, a perfectly reasonable thing, if you've banned me from usingat()
on temporaries?Storing references to temporaries is just a problem C++ programmers have to deal with, unfortunately.
To answer your new question, yes, you can do this:
只是一个想法:
以某种方式禁用向量上的复制构造函数。
无论如何,隐式复制数组并不是一件好事。 (想知道为什么 STL 作者决定定义这样的 ctor)
它将解决像你提到的问题,并且作为奖励将迫使你使用更有效的函数版本:
Just an idea:
To disable copying constructor on the vector somehow.
Implicit copying of arrays is not that good thing anyway. (wondering why STL authors decided to define such ctor at all)
It will fix problems like you've mentioned and as a bonus will force you to use more effective version of your function: