- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
基于“现代 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/
如果我不定义自己的构造函数,Base *b = new Base; 与 Base *b = new Base(); 之间有什么区别吗? 最佳答案 初始化是标准中要遵循的一种 PITA...然而,这两个
是否有现成的函数可以在 C# 中进行基本转换?我希望将以 26 为基数和以 27 为基数的数字转换为以 10 为基数。我可以在纸上完成,但我不是一个非常有经验的程序员,如果可能的话,我宁愿不要从头开始
JNA 中'base'是什么意思 Pointer.getPointerArray(long base) Pointer.getStringArray(long base) ? JNA Document
我正在做一个将数字从 10 进制转换为 2 进制的基本程序。我得到了这段代码: #include #include #include #include using namespace std;
“假设以下代码: public class MultiplasHerancas { static GrandFather grandFather = new GrandFather();
当我分析算法的时候,我突然问自己这个问题,如果我们有三元计算机时间复杂度会更便宜吗?还是有任何基础可以让我们构建计算机,这样时间复杂度分析就无关紧要了?我在互联网上找不到太多,但是基于三元的计算机在给
一个简化的场景。三个类,GrandParent,Parent 和 Child。我想要做的是利用 GrandParent 和 Parent 构造函数来初始化一个 Child 实例。 class Gran
我编写了一个简单的函数来将基数为 10 的数字转换为二进制数。我编写的函数是我使用我所知道的简单工具的最佳尝试。我已经在这个网站上查找了如何执行此操作的其他方法,但我还不太了解它。我确定我编写的函数非
我尝试了以下代码将数字从 base-10 转换为另一个 base。如果目标基地中没有零(0),它就会工作。检查 79 和 3 并正确打印正确的 2221。现在尝试数字 19 和 3,结果将是 21 而
这个问题在这里已经有了答案: Is Big O(logn) log base e? (7 个答案) 关闭 8 年前。 Intro 练习 4.4.6 的大多数解决方案。算法第三版说,n*log3(n)
如何判断基类(B)的指针是否(多态)重写了基类的某个虚函数? class B{ public: int aField=0; virtual void f(){}; }; class C
我测试了这样的代码: class A { public A() { } public virtual void Test () { Console.WriteL
两者都采用相同的概念:定义一些行和列并将内容添加到特定位置。但是 Grid 是最常见的 WPF 布局容器,而 html 中基于表格的布局是 very controversial .那么,为什么 WPF
我试图在 JS 中“获得”继承。我刚刚发现了一种基本上可以将所有属性从一个对象复制到另一个对象的简洁方法: function Person(name){ this.name="Mr or Miss
class A { public override int GetHashCode() { return 1; } } class B : A { pu
我有一个 Base32 信息哈希。例如IXE2K3JMCPUZWTW3YQZZOIB5XD6KZIEQ ,我需要将其转换为base16。 我怎样才能用 PHP 做到这一点? 我的代码如下所示: $ha
我已经使用其实验界面对 Google Analytics 进行了一些实验,一切似乎都运行良好,但我无法找到 Google Analytics 属性如何达到变体目标的答案,即归因 session - 基
if (state is NoteInitial || state is NewNote) return ListView.builder(
MSVC、Clang 和 GCC 不同意此代码: struct Base { int x; }; struct Der1 : public Base {}; struct Der2 : public
我已经尝试构建一个 Base 10 到 Base 2 转换器... var baseTen = window.prompt("Put a number from Base 10 to conver
我是一名优秀的程序员,十分优秀!