3

関数を実装したい場合:

template <typename TIterator>
void doSomething(TIterator begin, TIterator end);

両方で作業できるようにするには:

std::vector<Widget*>

std::vector<std::shared_ptr<Widget>>

基になるポインタにアクセスするにはどうすればよいですか?何らかの理由std::shared_ptr<Widget>で暗黙的にに変換できず、関数Widget*を使用する必要がありget()ます。このように、機能がないためstd::vector<Widget*>、コードは機能しません。Widget*get()

私がしていることはこれです:

void functionAcceptingPointer(Widget* widget);

template <typename TIterator>
void doSomething(TIterator begin, TIterator end);
{
    std::map<double, decltype(&(**begin))> map;
    ...
    auto firstPointer = &(**begin);
    ...
    functionAcceptingPointer(&(**begin));
    ....
}

つまり、通常のポインターが必要な場合は常に、二重逆参照*の後に&演算子を使用します。

それは仕事をしますが、これを行うためのより読みやすく、一般的に使用される方法があるかどうか、そしてコードを次のような醜いもので埋めた後に戻ってくることができるものがあるかどうかに興味があります&(**begin)

4

2 に答える 2

11

この問題を解決するために私がすることは次のとおりです。

#include <memory>

template <class T>
inline
T*
to_raw_pointer(T* p) noexcept
{
    return p;
}

template <class Pointer>
inline
typename std::pointer_traits<typename std::remove_reference<Pointer>::type>::element_type*
to_raw_pointer(Pointer&& p) noexcept
{
    return ::to_raw_pointer(p.operator->());
}
int main()
{
    std::shared_ptr<int> p1(new int(1));
    int* r1 = to_raw_pointer(p1);
    int* p2 = new int(2);
    int* r2 = to_raw_pointer(p2);
}
于 2013-03-12T18:11:43.477 に答える
3

読みやすさを向上させるために、任意の (スマート) ポインターを逆参照する独自のラッパーを作成できます。

template<typename T> auto raw_deref(T t) -> decltype( &**t ) { return &**t; }

あなたのコードを

template <typename TIterator>
void doSomething(TIterator begin, TIterator end)
{
    std::map<double, decltype(raw_deref(begin))> map;
    ...
    auto firstPointer = raw_deref(begin);
    ...
    functionAcceptingPointer(raw_deref(begin));
    ....
}

そしてもちろん、あなたはより良い名前を考えることができますraw_deref:)

于 2013-03-12T18:18:04.723 に答える