C++ 我怎样才能解决这个模棱两可的问题呢。有意思吗?
为了练习,我再次熟悉的主题之一是树木。深度优先搜索和广度优先搜索的区别在于,它们只在支持算法的数据结构的选择上有所不同 我想我可以编写一个公共树搜索,使用模板为堆栈(DFS)或队列(BFS)提供数据C++ 我怎样才能解决这个模棱两可的问题呢。有意思吗?,c++,templates,generics,mem-fun,C++,Templates,Generics,Mem Fun,为了练习,我再次熟悉的主题之一是树木。深度优先搜索和广度优先搜索的区别在于,它们只在支持算法的数据结构的选择上有所不同 我想我可以编写一个公共树搜索,使用模板为堆栈(DFS)或队列(BFS)提供数据stack和queue非常好,它们添加和删除的成员具有相同的名称。不幸的是,访问功能曾经被称为top,而另一个则被称为front。正因为如此,我没有完全到达我想要的地方。没有lambda我没能做到: template<typename T, typename D, typename G>
stack
和queue
非常好,它们添加和删除的成员具有相同的名称。不幸的是,访问功能曾经被称为top
,而另一个则被称为front
。正因为如此,我没有完全到达我想要的地方。没有lambda我没能做到:
template<typename T, typename D, typename G>
bool ts(Tree<T> const & tree, T const value, D & ds, G getter)
{
if (empty(tree))
{
return false;
}
ds.push(tree.Root);
while (!ds.empty())
{
auto const current = getter();
ds.pop();
if (current->Value == value)
{
return true;
}
if (current->Left)
{
ds.push(current->Left);
}
if (current->Right)
{
ds.push(current->Right);
}
}
return false;
}
template<typename T>
bool dfs(Tree<T> const & tree, T const value)
{
stack<typename Tree<T>::Node const * const> ds;
return ts(tree, value, ds, [&ds](){ return ds.top(); });
}
template<typename T>
bool bfs(Tree<T> const & tree, T const value)
{
queue<typename Tree<T>::Node const * const> ds;
return ts(tree, value, ds, [&ds](){ return ds.front(); });
}
但是,编译器会抱怨不明确(在const
和非const
版本之间)
所以我搜索了互联网,了解到我应该显式地提供模板类型
template<typename T>
bool dfs(Tree<T> const & tree, T const value)
{
typedef stack<typename Tree<T>::Node const * const> DataStructure;
return ts(tree, value, DataStructure(), mem_fun</*???*/>(&DataStructure::top));
}
模板
布尔dfs(树常数和树,T常数值)
{
typedef堆栈数据结构;
返回ts(树、值、DataStructure()、mem_-fun(&DataStructure::top));
}
遗憾的是,?的许多可能性我都不能满足编译器的要求
有人能给我一个提示吗
更新:这里是一个完整的工作示例(除非您定义了无LAMBDA):
#包括
#包括
#包括
使用名称空间std;
模板
结构树
{
结构体类型
{
T值;
节点*左;
节点*右;
节点(T值):值(value),左(nullptr),右(nullptr){
虚拟节点()
{
如果(左)删除左;
如果(右)删除右;
}
};
节点*根;
Tree():根(nullptr){}
virtual~Tree(){if(Root)delete Root;}
};
模板无效插入(类型名树::节点*节点,T常量和值)
{
typename树::节点**选定=&(值<节点->值?节点->左:节点->右);
如果(*已选定)
插入(*选定,值);
其他的
*所选=新类型名树::节点(值);
}
模板无效插入(树和树,T值)
{
如果(!tree.Root)
tree.Root=新类型名tree::Node(值);
其他的
插入(tree.Root,value);
}
模板
布尔ts(树常数和树、T常数值、D和D、G getter)
{
如果(!tree.Root)返回false;
ds.push(tree.Root);
而(!ds.empty())
{
auto const current=getter();
ds.pop();
如果(当前->值==值)返回true;
如果(当前->左)ds.push(当前->左);
如果(当前->右侧)ds.push(当前->右侧);
}
返回false;
}
模板
布尔dfs(树常数和树,T常数值)
{
typedef typename树::节点常量*数据结构内容;
typedef堆栈数据结构;
#如果定义了此项,则它将中断。
返回ts(树、值、数据结构(),
mem_-fun(static_cast(&DataStructure::top));
#否则//。
数据结构;
返回ts(树,值,ds,[&ds](){return ds.top();});
#恩迪夫
}
int main()
{
树木;
插入(树,5);
插入(树,2);插入(树,1);插入(树,3);
插入(树,7);插入(树,6);插入(树,9);
cout您可以将成员函数指针强制转换为所需的类型:
mem_fun( static_cast< R (DataStructure::*)( Args... ) >( &DataStructure::top ) )
或
c) 在ts
中,您尝试在没有对象的情况下调用getter
。您需要将其更改为:
auto const current = getter( &ds );
有了这些更改,代码对我有效。您可以将成员函数指针强制转换为所需的类型:
mem_fun( static_cast< R (DataStructure::*)( Args... ) >( &DataStructure::top ) )
或
c) 在ts
中,您尝试在没有对象的情况下调用getter
。您需要将其更改为:
auto const current = getter( &ds );
有了这些更改,代码就适合我了。将一些typedef定义为:
typedef typename DataStructure::reference reference;
typedef typename DataStructure::const_reference const_reference;
typedef reference (DataStructure::*top_type)(); //non-const version
typedef const_reference (DataStructure::*ctop_type)() const;//const version
然后用你需要的任何东西
在发布的代码中,您需要const version,因此请编写以下代码:
mem_fun( static_cast<ctop_type>(&DataStructure::top ))
如果getter
是从std::mem_fun
返回的对象,则这是一个错误,在这种情况下,应该像下面这样调用它:
auto const current = getter();
auto const current = getter(&ds);
请参阅此演示:
或者,如果您只是将指针传递给成员,那么您可以调用为:
auto const current = (ds.*getter)();
见:
比较三者,看看它们的区别
希望这能有所帮助。将一些typedef定义为:
typedef typename DataStructure::reference reference;
typedef typename DataStructure::const_reference const_reference;
typedef reference (DataStructure::*top_type)(); //non-const version
typedef const_reference (DataStructure::*ctop_type)() const;//const version
然后用你需要的任何东西
在发布的代码中,您需要const version,因此请编写以下代码:
mem_fun( static_cast<ctop_type>(&DataStructure::top ))
如果getter
是从std::mem_fun
返回的对象,则这是一个错误,在这种情况下,应该像下面这样调用它:
auto const current = getter();
auto const current = getter(&ds);
请参阅此演示:
或者,如果您只是将指针传递给成员,那么您可以调用为:
auto const current = (ds.*getter)();
见:
比较三者,看看它们的区别
希望能有所帮助。您能提供一个简短完整的示例吗?顺便说一句,您正在将ts()
中的左值引用(D&ds
)绑定到dsf()
中的右值(DataStructure()
)如果编译器接受它,那就不好。你不应该这么做。一般来说,给C++库成员函数指针不是可移植的,因为库实现允许用默认参数添加附加参数。你能产生一个简短的完整例子吗?顺便说一下,你正在绑定一个LValk引用。(ts()
中的D&ds
)到右值(DataStructure()
中的dsf()
)如果编译器接受它,那是不好的。一般来说,把指针指向C++库成员函数是不可移植的,因为库实现允许添加附加参数的默认参数。好点与<代码> Mimyfn < /C> >,但我的STL似乎没有那个。您正在使用哪种编译器?如果您使用GCC,请尝试使用-std=c++11
(或-std=c++0x
)选项编译代码。尝试了您的和Daniel的解决方案。两者都不起作用。Clang(在本例中)总是抱怨“重载函数'top'的地址”不可静态强制转换。是的,我正在使用