4

私のクラスSomeTypeに、(キーを使用して)マップから要素を返すメソッドがある場合

std::unique_ptr<OtherType> get_othertype(std::string name)
{
   return otMap.find(name);
}

これにより、発信者はコピーではなく、マップ内のポインターへのポインターを受け取ることができますか?これを実行しても大丈夫ですか、それともコピーコンストラクターを呼び出そうとしますか(削除されたため失敗します)、返されるのでしょうか?

マップアイテムとしてunique_ptrを使用する必要があると仮定します。

アップデート::

コードを実装しようとした後、unique_ptrとstd:map /:pairはgcc 4.4.4で一緒に機能しないようです。ペアは、型パラメーターとしてunique_ptrが好きではありませんでした。(MoveConstructiblesのマップを作成できないを参照してください)。

ptrをstd::shared_ptrに変更しましたが、すべて機能しました。

共有ポインタで同じコードを使用できると思いますか?

4

4 に答える 4

13

のモデルはunique_ptr所有権の譲渡ですunique_ptr関数からオブジェクトにを返す場合unique_ptr、システム内の他のオブジェクトが同じオブジェクトを参照できない可能性があります。

それはあなたが望むものですか?私はそれを非常に疑っています。もちろん、生のポインタを返すだけでもかまいません。

OtherType* get_othertype(const std::string& name)
{
    return otMap.find(name)->second.get();
}

したがって、クライアントはオブジェクトにアクセスできますが、マップは引き続きオブジェクトを所有します。

名前の下にエントリが見つからない場合、上記の解決策はかなり脆弱です。より良い解決策は、例外をスローするか、その場合はnullポインタを返すことです。

#include <stdexcept>

OtherType* get_othertype(const std::string& name)
{
    auto it = otMap.find(name);
    if (it == otMap.end()) throw std::invalid_argument("entry not found");
    return it->second.get();
}

OtherType* get_othertype(const std::string& name)
{
    auto it = otMap.find(name);
    return (it == otMap.end()) ? 0 : it->second.get();
}

完全を期すために、参照を返すというAnthonyの提案を次に示します。

OtherType& get_othertype(const std::string& name)
{
    auto it = otMap.find(name);
    if (it == otMap.end()) throw std::invalid_argument("entry not found");
    return *(it->second);
}

そして、これがマップ内への参照を返す方法ですがunique_ptr、クライアントが誤って元のファイルを変更しないように、それをconstへの参照にしましょう。

unique_ptr<OtherType> const& get_othertype(const std::string& name)
{
    auto it = otMap.find(name);
    if (it == otMap.end()) throw std::invalid_argument("entry not found");
    return it->second;
}
于 2010-09-23T10:59:49.730 に答える
2

の種類はotMap何ですか?

右辺値としてotMap.find(name)aを返す場合、これは正常に機能します。std::unique_ptr<OtherType>ただし、ポイントされた値の所有権は返されたポインターに転送されたため、値はマップに存在しなくなります。これは、ではなくカスタムマップタイプを使用していることを意味しますstd::map<>

マップに値を設定してその値へのポインタを返すことができるようにする場合はstd::shared_ptr<OtherType>、マップ値タイプと戻りタイプの両方としてを使用する必要がありますget_othertype()

std::map<std::string,std::shared_ptr<OtherType>> otMap;
std::shared_ptr<OtherType> get_othertype(std::string name)
{
    auto found=otMap.find(name);
    if(found!=otMap.end())
        return found->second;
    return std::shared_ptr<OtherType>();
}
于 2010-09-23T10:59:16.203 に答える
0

otMap.findは右辺値を返すため、RVOされていない場合、この右辺値は移動されます。しかし、もちろん、マップにはその特定のオブジェクトが含まれていません。また、前回チェックしたときに、findは値型ではなくイテレーターを返します。

于 2010-09-23T10:46:15.423 に答える
0

マップを変更して、shared_ptrsではなくsを保持することを検討しますunique_ptrか?これにより、値を返すのがはるかに安全になります。の全体的なポイントunique_ptrは、それがユニークである(つまり共有されていない)ということです。

于 2010-09-23T21:37:40.880 に答える