访问图形包属性类型,以在SFINAE中使用它

问题描述 投票:0回答:2

我有一些代码可以处理不同类型的(增强)图,我想对具有某些特定bundle属性的图做一些特殊的事情。

例如,此:

struct VertexProp
{
    // some data
};

我的代码可以使用两种类型的图形:

using graph1_t  = boost::adjacency_list<
    boost::vecS,
    boost::vecS,
    boost::undirectedS,
    VertexProp
    > ;

using graph2_t = boost::adjacency_list<
    boost::vecS,
    boost::vecS,
    boost::undirectedS
    > ;

我的意图是使用SFINAE启用仅处理此特定情况的功能:

template<Graph_t>
void foo
(
    const Graph_t& gr,
    std::enable_if<
        std::is_equal<SOME_TRAIT<Graph_t>::type,VertexProp>,T
        >::type* = nullptr
)
{
    // do something only for graphs having VertexProp
}

我一般情况下都可以使用类型特征(至少,我认为是...),但是在这种情况下,它是第三方类型(boost::adjacency_list)。

而且我在the provided traits中找不到给我该类型的typedef。我也检查了手册中的the included code,但没有帮助。

如何访问该类型?

c++ typetraits boost-graph
2个回答
1
投票

您可以使用模板模板参数来命名某些Graph_t的嵌套类型,然后确定是否有任何嵌套类型为VertexProp,如下所示:

template<template<typename ...> class Graph_t, typename ...Props>
auto foo(Graph_t<Props...>) 
  -> std::enable_if_t<
      std::disjunction<std::is_same<VertexProp, Props>...>{}>
{} 

您得到:

foo(graph1_t{});  // ok
foo(graph2_t{});  // error

0
投票

您可以通过property_map特性获得类型。实际上,值类型是该属性映射的特征:)

因此要检测顶点束:

template <typename Graph, typename Bundle = typename boost::property_map<Graph, boost::vertex_bundle_t>::type>
    using VBundle = typename boost::property_traits<Bundle>::value_type;

要检查它是否为预期的类型:

template <typename Graph>
    using HasVertexProp = std::is_same<VertexProp, VBundle<Graph> >;

现在您可以使用SFINAE。或者,像我这样的情况建议:标签分发;

namespace detail {
    template <typename Graph_t>
    void foo(const Graph_t& g, std::true_type) {
        print_graph(g, std::cout << "Graph with VertexProp bundle: ");
    }

    template <typename Graph_t>
    void foo(const Graph_t& g, std::false_type) {
        print_graph(g, std::cout << "Graph with other/missing properties: ");
    }
}

template <typename Graph_t>
void foo(const Graph_t& g) {
    detail::foo(g, HasVertexProp<Graph_t>{});
}

让我们测试一下:

Live On Coliru

int main() {
    graph1_t g1(4);
    graph2_t g2(4);
    foo(g1);
    foo(g2);
}

打印

Graph with VertexProp bundle: 0 <--> 
1 <--> 
2 <--> 
3 <--> 
Graph with other/missing properties: 0 <--> 
1 <--> 
2 <--> 
3 <--> 
© www.soinside.com 2019 - 2024. All rights reserved.