加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C模板函数(基于Modern C Design)编译错误

发布时间:2020-12-16 06:54:31 所属栏目:百科 来源:网络整理
导读:基于“现代C设计”一书中的第5章(广义函子) 我正在尝试编写一个Functor模板.在问我“为什么我不直接使用Boost的绑定或Loki?”之前简单的答案是“因为我想学习.” 话虽这么说,我已经按照这本书,并使用示例代码作为参考,但我不断提出编译时错误,我似乎无法理
基于“现代C设计”一书中的第5章(广义函子)

我正在尝试编写一个Functor模板.在问我“为什么我不直接使用Boost的绑定或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,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定义,它会找到一个?

如果我错了,请纠正我,这只是我理解有限的最好的buess.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读