gpt4 book ai didi

C++ Templated Functor (based on Modern C++ Design)编译错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:09 24 4
gpt4 key购买 nike

基于“现代 C++ 设计”一书中的第 5 章(广义仿函数)

我正在尝试编写一个 Functor 模板。在问我“为什么我不直接使用 Boost 的绑定(bind)或 Loki?”之前简单的回答是“因为我想学习。”

话虽这么说,我已经按照这本书做了,也使用了示例代码作为引用,但我一直遇到编译时错误,而且我似乎不明白为什么。

当我修改本书的示例代码以不使用线程模型时,这些示例工作正常。但是我的代码没有。这是相关代码:

非常基本的 TypeList,以及 TypeAt 和 Nulltype,EmptyType(也基于本书)

<TypeList.hpp>
---
class NullType
{};

class EmptyType
{};

#define TYPELIST_1(T1) TypeList<T1, NullType>
#define TYPELIST_2(T1,T2) TypeList<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1,T2,T3) TypeList<T1, TYPELIST_2(T2, T3) >


template < typename T, typename U >
struct TypeList
{
typedef T Head;
typedef U Tail;
};


namespace typelist
{

template <class TList, unsigned int i > struct TypeAt;
template <class Head, class Tail >
struct TypeAt<TypeList<Head, Tail>,0 >
{
typedef Head Result;
};

template <class Head, class Tail, unsigned int i >
struct TypeAt<TypeList<Head, Tail>, i >
{
typedef typename TypeAt<Tail, i-1>::Result Result;
};

template <class TList, unsigned int index,
typename DefaultType = NullType>
struct TypeAtNonStrict
{
typedef DefaultType Result;
};
}
---

使用这些当然是Functor

<Functor.hpp>
---
namespace functorPrivate
{
template<typename R>
struct FunctorBase
{
typedef R ResultType;
typedef EmptyType Param1;
private:
};
}

template <typename R, class TList>
class FunctorImpl;

template <typename R>
class FunctorImpl<R, NullType > : public functorPrivate::FunctorBase<R>
{
public:
typedef R ResultType;

virtual ~FunctorImpl(){}
virtual R apply() = 0;
};

template <typename R, typename P1>
class FunctorImpl<R, TYPELIST_1(P1) > : public functorPrivate::FunctorBase<R>
{
public:
typedef R ResultType;
typedef P1 Param1;

virtual ~FunctorImpl(){}
virtual R apply(P1) = 0;

};

template < class ParentFunctor, typename Fun>
class FunctionHandler : public ParentFunctor::Impl
{
private:
typedef typename ParentFunctor::Impl Base;
Fun fun;
public:
typedef typename Base::ResultType ResultType;
typedef typename Base::Param1 Param1;

FunctionHandler(const Fun& fun) :
fun(fun)
{}
virtual ~FunctionHandler()
{}

virtual ResultType apply()
{
return fun();
}

virtual ResultType apply(Param1 p1)
{
return fun(p1);
}

};

template <typename R, class TList = NullType>
class Functor
{
public:
typedef TList ParamList;
typedef R ResultType;
typedef FunctorImpl<R, TList> Impl;
typedef typename Impl::Param1 Param1;

Functor() :
impl(0)
{}
//Function / Handling functor type templated constructor
template<class Fun>
Functor(const Fun& fun) :
impl(new FunctionHandler< Functor, Fun>(fun))
{}

//apply functions
R apply()
{
return (*impl).apply();
}

R apply(Param1 p1)
{
return (*impl).apply(p1);
}
private:
std::auto_ptr<Impl> impl;

};

---

当我尝试这样使用时:

---
class TestFunctor0
{
public:
int operator()()
{
cout << "zero param functor" << endl;
return 1;
}
};

//somewhere in main...

TestFunctor0 f;
Functor<int, NullType> command(f);
int res = command.apply();
CPPUNIT_ASSERT_EQUAL(1, res);
---

我收到以下编译时错误:

../../../include/real/Functors.hpp: In member function ‘typename ParentFunctor::Impl::ResultType FunctionHandler<ParentFunctor, Fun>::apply(typename ParentFunctor::Impl::Param1) [with ParentFunctor = Functor<int, NullType>, Fun = TestFunctor0]’:
main.cpp:246: instantiated from here
../../../include/real/Functors.hpp:74: error: no match for call to ‘(TestFunctor0) (EmptyType&)’
main.cpp:31: note: candidates are: int TestFunctor0::operator()()

有人知道为什么我会看到这个问题吗?我没主意了。谢谢

最佳答案

这个问题已经解决了。事实证明,在 FunctionHandler 中,将 apply() 函数设为虚拟是导致问题的原因。删除虚拟关键字后,一切都进行得很顺利。

我仍然不太确定为什么这会如此彻底地改变事情,但它解决了问题。我对原因的最佳猜测是,通过添加虚拟,编译器将尝试使用正确的函数填充 vtable,并且由于 Param1 是/技术上/由 NullType 定义的,它会找到那个吗?

如有不妥请指正,这简直是我理解有限的最佳方案。

关于C++ Templated Functor (based on Modern C++ Design)编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3412476/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com