2

Boost Graph Library にバンドルされたプロパティを標準ライブラリ型で使用しながら、その型の<<ストリーム演算子のオーバーロードを使用して満たすことはできwrite_graphvizますか?

#include <boost/graph/graphviz.hpp>

namespace boost {
  namespace detail {
    namespace has_left_shift_impl {
      template <typename T>
      inline std::ostream &operator<<(std::ostream &o, const std::array<T,2> &a) {
        o << a[0] << ',' << a[1];
        return o;
      }
    }
  }
}

static_assert(boost::has_left_shift<
                std::basic_ostream<char>,
                std::array<double,2>
              >::value,"");

int main()
{
  using namespace boost;
  typedef adjacency_list<vecS, vecS, directedS, no_property, std::array<double,2>> Graph;
  Graph g;
  add_edge(0, 1, {123,456}, g);
  write_graphviz(std::cout, g, default_writer(),
                   make_label_writer(boost::get(edge_bundle,g)));
  return 0;
}

Boost の静的アサートに直面したため、コードを上記のように変更しました。hereからの提案を採用し、<<実装はboost::detail::has_left_shift_impl名前空間内で定義されます。悲しいかな、私は今別のエラーに直面しています:

/usr/include/boost/lexical_cast.hpp:1624:50: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
                 bool const result = !(out_stream << input).fail();

<<で使用できるオーバーロードを提供する方法はありwrite_graphvizますか? Ubuntu 14.10 と GCC 4.9.1 を使用しています。

4

1 に答える 1

3

あなたもできなかった

std::cout << g[add_edge(0,1,{123,456},g)];

例を提供せずに

inline static std::ostream& operator<<(std::ostream& os, std::array<double, 2> const& doubles) {
    return os << "{" << doubles[0] << "," << doubles[1] << "}";
}

現在、これらのオーバーロードlexical_castを適切なタイミングで取得することは、移植可能に実行するのが非常に困難です (主に、ADL がstd::arrayandを支援しないためですdouble)。

代わりに、値変換プロパティ マップを使用できます (もちろん読み取り専用です)。

std::string prettyprint(std::array<double, 2> const& arr) {
    std::ostringstream oss;
    oss << "{" << arr[0] << "," << arr[1] << "}";
    return oss.str();
}

その後make_transform_value_property_map(prettyprint, get(edge_bundle, g))

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>

using namespace boost;

std::string prettyprint(std::array<double, 2> const& arr) {
    std::ostringstream oss;
    oss << "{" << arr[0] << "," << arr[1] << "}";
    return oss.str();
}

int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, std::array<double,2>> Graph;
    Graph g;
    add_edge(0, 1, {123,456}, g);
    write_graphviz(std::cout, g, default_writer(),
            make_label_writer(make_transform_value_property_map(&prettyprint, get(edge_bundle, g))));
}

版画

digraph G {
0;
1;
0->1 [label="{123,456}"];
}
于 2015-04-30T01:12:34.117 に答える