次のコード
#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) では、ベクトル引数が右辺値である場合、削除された関数宣言を使用して呼び出しを完全に禁止できます。at
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
右辺値オブジェクトのメンバー関数の呼び出しは引き続き許可されるためです。この種の呼び出しを禁止する方法はありますか?
修理:
上記の例は、私が実際のプロジェクトで行ったことではありません。C++ 2011 が次のようなメンバー関数の修飾をサポートしているかどうか疑問に思っています
class A {
void func() rvalue; // Then a call on an rvalue object goes to this overload
void func() const;
};
修理:
それは素晴らしいことですが、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;
}
どうもありがとう!