【问题标题】:Getting/deducing type in template-function for return value在模板函数中获取/推断类型以获取返回值
【发布时间】:2010-11-17 10:34:07
【问题描述】:

我正在使用 Boost Graph Library 并在此基础上构建了自己的类。

现在,我有以下功能:

template< class VERTEXPROPERTIES >
VERTEXPROPERTIES& properties(const Vertex& v) const
{   
    typename property_map<FilteredGraphContainer, vertex_properties_t>::const_type param = get(vertex_properties, graph_);

    return param[v];
}

当我在这样的类模板中使用这个函数时:

template< class VERTEXPROPERTIES, class EDGEPROPERTIES >
class Graph
{
// all the code
};

它有效。 但是,当我想在这样的类中使用它时:

template < class GRAPH, class EDGE_PREDICATE, class VERTEX_PREDICATE >
class FilteredGraph
{
// all the code
};

并将 properties() 函数应用于 FilteredGraph 对象,编译器抱怨它找不到该函数。
据我目前发现,这可能是由于参数列表中缺少模板参数。
对于 Graph 类,这个模板参数很容易找到,因为它是在创建 Graph 对象时定义的。
但是对于FilteredGraph,应该可以从GRAPH-template参数中推导出来。
再说一次,我认为编译器仍然会在获取正确的返回值类型时遇到问题,因为这可能需要事先找出...
我真的很想在 properties() 函数中保留这个概念,因为它允许保持其他函数的通用性。
您有什么想法可以解决这个问题,并可能保留这个概念吗?

【问题讨论】:

  • 请发布编译错误和类定义。你给我们没有信息。
  • 对此我深表歉意。我没有在这里发布这个,因为我觉得它只会使问题变得混乱。编译器错误只是它找不到我的代码中使用的函数。我能够将其修复为 boost 库提供的 property_traits 功能。我会单独发布答案。
  • 不,别担心。我不会混淆答案。编译错误通常非常有用。有时有点神秘,但更多时候,非常精确。

标签: c++ templates boost return-value


【解决方案1】:

再次抱歉,我没有提供更多信息。
在我看来,编译器无法在那里推断出依赖类型。我之前在使用模板时遇到过这个问题。
我将在此处提供修复,以防有人遇到类似问题。

FilteredGraph 使用 Graph 的实例(基本上是具有内部自定义属性的 adjacency_list)作为其输入。 Graph 类有两个模板参数,一个用于顶点的属性,一个用于边的属性。
作为一个小旁注,使用捆绑属性(旧版本的 boost 图形库不支持,某些编译器也不支持),我认为这个问题可以被规避,因为你不需要返回 a 值的额外函数(可能)未知类型。 因为需要为某些特定类型的顶点/边属性指定传递给 FilteredGraph 的 Graph 对象,所以实际上可以提取此信息。
我通过以下方式实现了这一点:

/// Type of the internal properties of the edges
typedef typename property_traits< typename property_map<FilteredGraphContainer, vertex_properties_t>::type >::value_type VProps;
/// Type of the internal properties of the edges
typedef typename property_traits< typename property_map<FilteredGraphContainer, edge_properties_t>::type >::value_type EProps;

然后定义:

VProps& properties(const Vertex& v)
{
        typename property_map<FilteredGraphContainer, vertex_properties_t>::type param = get(vertex_properties, graph_);
        return (param[v]);
}

再次感谢您对此问题的关注,很抱歉没有提供更多信息。

最好的问候。

【讨论】:

  • 您可以使用问题左侧的勾号接受您的答案(包括您自己的)。这会将问题标记为已回答,并让有相同问题的其他人更容易找到解决方案。
  • 我认为你应该使用更多的typedef。你的代码行很长。
  • 关于“接受你的答案”,它说我只能在两天内标记为已解决。感谢您的提示。
  • 关于typedef,肯定会提高可读性。但是,有些读者可能对此感到困惑。
  • 那么你是我知道的第一个声称 typedef 令人困惑的人 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-14
相关资源
最近更新 更多