C++ 访问图形束属性类型,以便在SFINAE中使用
我有一些代码可以处理不同类型的(boost)图,我想为具有特定bundle属性的图做一些特殊的事情 例如,这:C++ 访问图形束属性类型,以便在SFINAE中使用,c++,typetraits,boost-graph,C++,Typetraits,Boost Graph,我有一些代码可以处理不同类型的(boost)图,我想为具有特定bundle属性的图做一些特殊的事情 例如,这: struct VertexProp { // some data }; 我的代码可以使用两种类型的图形: using graph1_t = boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, VertexProp > ; 使用graph
struct VertexProp
{
// some data
};
我的代码可以使用两种类型的图形:
using graph1_t = boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::undirectedS,
VertexProp
> ;
使用graph1\u t=boost::邻接列表<
boost::vecS,
boost::vecS,
boost::无向,
垂直旋转
> ;
或
使用图形2\u t=boost::邻接列表<
boost::vecS,
boost::vecS,
boost::无向
> ;
我的目的是使用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
}
模板
福娃
(
常数图,
std::启用_if<
std::等于T吗
>::type*=nullptr
)
{
//仅对具有VertexProp的图形执行某些操作
}
我对一般情况下的类型特征没有意见(至少我认为是这样),但在这种情况下,它是第三方类型(boost::adjacence\u list
)
我在typedef中找不到给我那种类型的。
我也查阅了手册,但没有帮助
如何访问该类型?您可以使用模板参数来命名某些
图形的嵌套类型,然后确定是否有任何嵌套类型是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>...>{}>
{}
您可以通过属性映射
trait获取类型。事实上,值类型是该属性映射的一个特征:)
因此,要检测顶点束:
template <typename Graph, typename Bundle = typename boost::property_map<Graph, boost::vertex_bundle_t>::type>
using VBundle = typename boost::property_traits<Bundle>::value_type;
现在你可以使用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>{});
}
印刷品
Graph with VertexProp bundle: 0 <-->
1 <-->
2 <-->
3 <-->
Graph with other/missing properties: 0 <-->
1 <-->
2 <-->
3 <-->
带有VertexProp束的图形:0
1.
2.
3.
具有其他/缺少属性的图形:0
1.
2.
3.
谢谢您的回答,我需要一些时间来分析。当然可以。请随意提问。如果另一个模板参数匹配,这也会起作用。最好是通读图书馆的特点。@sehe我不知道你的意思。这会检查模板参数是否匹配。哦,我想我明白了。无论如何,我会留下这个答案,因为它可能对OP有用。谢谢(再次)Sehe,你是我真正的BGL导师!;-)我会仔细检查的。我喜欢标记分派方法。@kebs顺便说一句,我希望混合中有更多的类型,否则您可以简单地foo(graph1\u t){;foo(图形),代码>:)但是的,这甚至适用于其他模型:啊,是的,当然是重载。事实上,我不能在我的用例中使用重载,因为代码实际上是库的一部分,并且只有在某些特定的“showcase”中我才需要一个bundle属性(并检测它)。但在一般情况下,我需要坚持使用一般的图类型,因此我将坚持使用您描述的方法。好的,刚刚尝试过,非常完美,非常优雅的解决方案!谢谢。同样,在BGL手册中查找信息并不容易。(供参考,此处为:)
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> >;
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>{});
}
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 <-->