说我有:
std::multimap< std::string, netCDF_Dimension > dimensions;
和类似的多重映射。 偶尔我需要:
std::multimap< std::string, netCDF_Attribute<U> > attributes;
其中U是例如netCDF_VarAtt或netCDF_GlobalAtt。
我可以写一个搜索功能:
template<class T>
boost__optional<T*> Search(const std::multimap< std::string, T > currMap){
//Search in map.
if found
return T*;
else
return boost::none
}
这适用于标准类型/类,但不适用于netCDF_Attribute<U>
。这超出了我对模板的简单理解。我需要的是:
T = netCDF_Attribute<U>
以及明显的类型,有解决方案吗?
以下代码使用简单类型/类netCDF_Attribute<U>
调用类的完整代码是:
template<typename U>
class netCDF_Attributes{
std::multimap< std::string, netCDF_Attribute<U> > attributes;
public:
boost::optional< std::pair< netCDF_Element, void * > > Find(std::vector< std::string >::const_iterator currStep,
std::vector< std::string >::const_iterator lastStep);
void Initialise( std::multimap< std::string, U > &attMap );
};
template<typename U>
boost::optional< std::pair< netCDF_Element, void * > > netCDF_Attributes< U >::Find(std::vector< std::string >::const_iterator currStep,
std::vector< std::string >::const_iterator lastStep){
netCDF_Crawler crawl;
return crawl.Find(attributes, currStep, lastStep);
}
template<typename U>
void netCDF_Attributes< U > :: Initialise(std::multimap< std::string, U > &attMap ){
for ( auto iter : attMap )
attributes.insert( std::pair< std::string, netCDF_Attribute< U > >( iter.first, netCDF_Attribute< U >(iter.second) ) );
}
enum netCDF_Element {groupElement, attributeElement, dimensionElement, variableElement, dataElement};
class netCDF_Crawler {
public:
template<typename T>
boost::optional<T * > Shallow_Search_List(const std::multimap< std::string, T > &currMap, std::string name);
template<typename T>
boost::optional< std::pair<netCDF_Element, void *> > Deep_Search_List(const std::multimap< std::string, T > &currMap,
std::vector< std::string >::iterator currStep,
std::vector< std::string >::iterator lastStep);
template<typename T>
boost::optional< std::pair< netCDF_Element, void * > > Find(const std::multimap< std::string, T > &currMap,
std::vector< std::string >::iterator currStep,
std::vector< std::string >::iterator lastStep);
};
template<typename T>
boost::optional<T * > netCDF_Crawler::Shallow_Search_List(const std::multimap< std::string, T > &currMap, std::string name){
for (auto iter : currMap)
if (iter.first == name)
return &iter.second;
return boost::none;
}
template<typename T>
boost::optional< std::pair< netCDF_Element, void * > > netCDF_Crawler::Deep_Search_List(const std::multimap< std::string, T > &currMap,
std::vector< std::string >::iterator currStep,
std::vector< std::string >::iterator lastStep){
for (auto iter : currMap)
if ( boost::optional< std::pair< netCDF_Element, void * > > res = iter.second.Find(currStep, lastStep) )
return res;
return boost::none;
}
template<typename T>
boost::optional< std::pair< netCDF_Element, void * > > netCDF_Crawler::Find(const std::multimap< std::string, T > &currMap,
std::vector< std::string >::iterator currStep,
std::vector< std::string >::iterator lastStep){
if (boost::optional< T* > currPtr = Shallow_Search_List< T >(currMap, *currStep))
// Found in map.
// This was the last element to find.
if (currStep == lastStep)
return std::pair< netCDF_Element, void * > ((*currPtr)->element, (void *) *currPtr);
else
// Try and find the next element
return (*currPtr)->Find(currStep+1, lastStep);
// Not found in curr map. Dig deeper. Look in subgroups.
else
return Deep_Search_List<T>(currMap, currStep, lastStep);
return boost::none;
}
第一条错误消息是:
Class_netCDF_Attributes.hpp: In instantiation of
‘boost::optional<std::pair<netCDF_Element, void*> > netCDF_Attributes<U>::Find
(std::vector<std::__cxx11::basic_string<char> >::const_iterator,
std::vector<std::__cxx11::basic_string<char> >::const_iterator)
[with U = netCDF::NcVarAtt;
std::vector<std::__cxx11::basic_string<char> >::const_iterator =
__gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >]’:
Class_netCDF_Variable.hpp:55:98: required from here
Class_netCDF_Attributes.hpp:34:51: error: no matching function for call to
‘netCDF_Crawler::Find(std::multimap<std::__cxx11::basic_string<char>, netCDF_Attribute<netCDF::NcVarAtt>, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, netCDF_Attribute<netCDF::NcVarAtt> > > >&,
std::vector<std::__cxx11::basic_string<char> >::const_iterator&,
std::vector<std::__cxx11::basic_string<char> >::const_iterator&)’
return crawl.Find(attributes, currStep, lastStep);
答案 0 :(得分:0)
简而言之:您提供了错误的参数类型。
在您的代码中很难发现,因为它相当混乱。因此,首先要解决问题的方法是首先将问题减少到MCVE。 这是一个很小的版本,可以重现你的错误:
struct netCDF_Crawler {
template<typename T>
T find(std::multimap<std::string,T> const&, std::vector<std::string>::iterator);
};
template<typename U>
struct netCDF_Attribute { U i=U{}; };
template<typename U>
struct netCDF_Attributes
{
std::multimap<std::string,netCDF_Attribute<U>> attributes;
netCDF_Attribute<U> find(std::vector<std::string>::const_iterator step)
{
netCDF_Crawler crawl;
return crawl.find(attributes,step);
}
};
template struct netCDF_Attributes<int>;
从这个代码看错误是显而易见的,但让我们看看clang说的是什么(顺便说一下,第二个非常有用的注释只是在减少了find()
的参数数量之后产生的3至2):
test.cc:21:18: error: no matching member function for call to 'find'
return crawl.find(a,step);
~~~~~~^~~~
test.cc:25:17: note: in instantiation of member function 'netCDF_Attributes<int>::find'
requested here
template struct netCDF_Attributes<int>;
^
test.cc:7:5: note: candidate function [with T = netCDF_Attribute<int>] not viable:
no known conversion from '__wrap_iter<const_pointer>' to '__wrap_iter<pointer>'
for 2nd argument
T find(std::multimap<std::string,T> const&, std::vector<std::string>::iterator);
^
1 error generated.
经过检查,我们发现netCDF_Crawler::find
将iterator
作为第二个参数,而netCDF_Attributes::find()
则提供const_iterator
。显然,这不会起作用。我留给你修理。