【问题标题】:Template class as template class parameter模板类作为模板类参数
【发布时间】:2016-05-03 09:18:41
【问题描述】:

在这个例子中,我创建了一个以函数为参数的 Functor 类。第二个函子应将第一个函子的对象作为模板参数,并调用第一个函子的函数。我不确定第二个 Functor 的模板应该是什么样子。

这是第一个 Functor,它按预期工作:

typedef float (*pDistanceFu) (float, float);
typedef float (*pDecayFu) (float, float, float);

template <pDistanceFu Dist, pDecayFu Rad, pDecayFu LRate>
class DistFunction {    
public:
  DistFunction() {}
  DistFunction(char *cstr) : name(cstr) {};

  char *name;
  float distance(float a, float b) { return Dist(a,b); };
  float rad_decay(float a, float b, float c) { return Rad(a,b,c); };
  float lrate_decay(float a, float b, float c) { return LRate(a,b,c); };
};

在这里我创建了一个专门的仿函数实例:

DistFunction<foo,bar,foobar> fcn_gaussian((char*)"gaussian");

这里我不知道模板的外观如何,将任何类型的 DistFunction<...> 作为参数

template<template<DistFunction> typename = F>
struct functor {
  float fCycle;
  float fCycles;

  functor(float cycle, float cycles) : fCycle(cycle), fCycles(cycles) {}

  float operator()(float lrate) {
    return (F.lrate_decay)(lrate, fCycle, fCycles);
  }
};

我想如何使用第二个仿函数:

typedef DistFunction<foo,bar,foobar> gaussian;
void test() {
  functor<gaussian> test(0,1);
}

错误:

error: argument list for class template "DistFunction" is missing
error: expected "class"
error: expected a "," or ">"

【问题讨论】:

  • 你将如何使用functorfunctor&lt;what_will_be_specified_here&gt;?
  • 更新了问题,可能编译器不可能从对象中获取模板信息..,我猜
  • 谁提供函子对象?
  • 你所有的char* 应该是const char*,然后你不需要转换文字字符串。

标签: c++ templates


【解决方案1】:
template<DistFunction> typename = F

这是一个未命名的模板模板参数,具有一个类型为 DistFunction 和默认值 F 的非类型参数。由于DistFunction 不是一个类型(它是一个类模板)并且F 不存在,所以这没有任何意义。

这里不需要任何模板模板参数。简单的

template<typename F>
struct functor {

应该做的工作。

如果你想限制F,也就是只允许它接受DistFunction的各种实例化而没有别的,你需要不同的语言设施,比如static_assert和/或enable_if。这只需要更好的错误消息,以防有人错误地实例化functor。只需使用F,就好像它是DistFunction

【讨论】:

  • 你是对的。我的错误是我忘记了构造函数。使成员静态使我的测试代码也能正常工作。我太笨了。
【解决方案2】:

试试

template<typename F>
struct functor {
  float fCycle;
  float fCycles;

  functor(float cycle, float cycles) : fCycle(cycle), fCycles(cycles) {}

  float operator()(float lrate) {
    return F((char*)"gaussian").lrate_decay(lrate, fCycle, fCycles);
  }
};

LIVE

【讨论】:

  • 这失败了,因为 lrate_decay 是未知的。此外,我想避免在运行时创建 DistFunction。
  • @dgrat 然后每次调用operator() of functor 时都需要创建它。
  • 这个演示什么都没有,你没有打电话给test.operator()
  • @n.m.我已将变量重命名为 tfunctor&lt;gaussian&gt; t(0.0f ,1.0f); t(2.0f);
  • @dgrat 链接的演示没有失败。如果您想避免运行时创建某个类的对象,请不要在此类中声明非静态成员,因为您将无法访问它们。也不要给这个类一个构造函数,因为你不会调用它。从 DistFunction 中删除构造函数和 name,使其他成员静态,使用此语法 F::lrate_decay 访问它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多