Iは、オブジェクトをロックするための次のクラスがあります。私は次のようにロックし、共有オブジェクトへのアクセスのロックを解除するためにそれを使用したい2つの異なるバージョンの矢印演算子がありますか?
#include <memory>
template <class Type, class Mutex>
class LockableObject {
public:
class UnlockedObject {
public:
UnlockedObject(Mutex &mutex, Type &object)
: mutex_(mutex), object_(object) {}
UnlockedObject(UnlockedObject &&other) = default;
// No copying allowed
UnlockedObject(const UnlockedObject &) = delete;
UnlockedObject &operator=(const UnlockedObject &) = delete;
~UnlockedObject() { mutex_.unlock(); }
Type *operator->() { return &object_; } // Version 1
// Type &operator->() { return object_; } // Version 2
private:
Mutex &mutex_;
Type &object_;
};
template <typename... Args>
LockableObject(Args &&... args) : object_(std::forward<Args>(args)...) {}
UnlockedObject Lock() {
mutex_.lock();
return UnlockedObject(mutex_, object_);
}
private:
Mutex mutex_;
Type object_;
};
を。第二の例は、自分自身を適用する->
事業者の能力を複数回を使用しています:
// Example 1
{
LockableObject<std::string, std::mutex> locked_string;
auto unlocked_string = locked_string.Lock();
// This is what I want:
unlocked_string->size(); // works for version 1, breaks for version 2
}
// Example 2
{
LockableObject<std::unique_ptr<std::string>, std::mutex> locked_string(std::unique_ptr<std::string>(new std::string()));
auto unlocked_string = locked_string.Lock();
// This is what I want:
unlocked_string->size(); // works for version 2, breaks for Version 1
// Workaround
unlocked_string->get()->size(); // works for version 1, but is not nice
}
クラスは何とか両方の例は、->get()
と回避策の代わりにunlocked_string->size()
を使っ持つように変更することができますか?おそらく、テンプレートの特殊化などを使用してですか?
:
そして、条件付きで、このような関数の2つのバージョンを有効または無効に:私は、矢印演算子の存在を検出するために、次を使用して終了しましたか? – Yakk
'unlocked_string() - > size()'のようなものを得るために 'operator()'をオーバーロードしてください。問題は本当にあなたの 'get()'が 'std :: unique_ptr'から来ていることです。 'get()'を取り除きたい場合は、 'unique_pointer'のテンプレートを特化しなければなりません – subzero
@subzeroは' unique_ptr'に特化しています。バージョン2の '型'にオーバーロードされた '演算子 - > 'と他の' Type'sのバージョン1はうまくいくでしょう...これを行う方法の詳細は? –