C++ 我怎样才能解决这个模棱两可的问题呢。有意思吗?

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>

为了练习,我再次熟悉的主题之一是树木。深度优先搜索和广度优先搜索的区别在于,它们只在支持算法的数据结构的选择上有所不同

我想我可以编写一个公共树搜索,使用模板为堆栈(DFS)或队列(BFS)提供数据
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'的地址”不可静态强制转换。是的,我正在使用