CTRP派生类中没有名为“ type”的类型 [英] No type named 'type' in CTRP derived class

查看:94
本文介绍了CTRP派生类中没有名为“ type”的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试验好奇重复模板模式 -argument functor,它有两种实现:一种使用有效的模板template参数,第二种尝试在接口类中访问派生的Functor :: type。在后一个示例中,编译器(gcc 5.4.0)报告

I've been experimenting with the Curiously Recurring Template Pattern for a generic single-argument functor and have two implementations: one using a template template parameter which works and a second where I try to access the derived Functor::type in the interface class. In the latter example, the compiler (gcc 5.4.0) reports


错误:没有名为'< 'struct Cube<中的strong> type ' double>’

error: no type named 'type' in 'struct Cube< double >'



template<class T, template<class> class Functor>
class FunctorInterface_1 {
private:
  const Functor<T> &f_cref;
public:
  FunctorInterface_1() : f_cref(static_cast<const Functor<T>&>(*this)) {}
  T operator() ( T val ) const { return f_cref(val); }
}; // FunctorInterface_1 (works)

template<class Functor>
class FunctorInterface_2 {
private:
  const Functor &f_cref;
public:
  using Ftype = typename Functor::type;
  FunctorInterface_2() : f_cref(static_cast<const Functor&>(*this)) {}
  Ftype operator() ( Ftype val ) const { return f_cref(val); }
}; // FunctorInterface_2 (no type in Functor!)

然后我尝试使用main中的T = double进行编译()以下两个类别中的():

I then try to compile with T=double in main() of the following two classes:

template<class T> 
struct Square : public FunctorInterface_1<T,Square> {
  T operator()( T val ) const { return val*val; }
}; // Square


template<class T>
struct Cube : public FunctorInterface_2<Cube<T>> {
  using type = T; 
  T operator() ( T val ) const { return val*val*val; }
}; // Cube

可以将FunctorInterface_2 / Cube示例修改为可以工作,还是
在第一个示例中,接口类是否必须在T上以
模板化?谢谢!

Can the FunctorInterface_2/Cube example be modified to work, or is it necessary for the interface class to be templated on T as in the first example? Thanks!

编辑:使用gcc -std = c ++ 14,我可以通过使用自动返回和参数类型来获得第二个示例来编译和运行
但是,据我了解,在FunctorInterface_1 :: operator()中,自动参数类型不是C ++ 14标准的一部分。

Using gcc -std=c++14, I can get the second example to compile and run by using auto return and argument types in FunctorInterface_1::operator(), however, as I understand, auto argument types are not part of the C++14 standard.

编辑2:好吧,我感觉有点厚。我刚刚意识到我可以在一个新参数上模板FunctorInterface_1 :: operator(),但是,对于我所考虑的应用程序,我真的希望我的基类能够访问在派生类中定义的类型。

EDIT 2: Well I feel a bit thick. I just realized that I could template FunctorInterface_1::operator() on a new parameter, however, for the application I have in mind, I would really like my base class to be able to access types defined in the derived class.

推荐答案

何时行

using Ftype = typename Functor::type;

在基类中处理,定义为 Functor 不可用。因此,您不能使用 Functor :: type

is processed in the base class, the definition of Functor is not available. Hence, you can't use Functor::type.

一种解决此限制的方法是定义

One way to get around this limitation is to define a traits class.

// Declare a traits class.
template <typename T> struct FunctorTraits;

template<class Functor>
class FunctorInterface_2 {
   private:
      const Functor &f_cref;
   public:

      // Use the traits class to define Ftype
      using Ftype = typename FunctorTraits<Functor>::type;

      FunctorInterface_2() : f_cref(static_cast<const Functor&>(*this)) {}
      Ftype operator() ( Ftype val ) const { return f_cref(val); }
}; // FunctorInterface_2 (no type in Functor!)

// Forward declare Cube to specialize FunctorTraits
template<class T> struct Cube;

// Specialize FunctorTraits for Cube
template <typename T> struct FunctorTraits<Cube<T>>
{
   using type = T; 
};

template<class T>
struct Cube : public FunctorInterface_2<Cube<T>> {
   using type = T; 
   T operator() ( T val ) const { return val*val*val; }
}; // Cube

工作代码: https://ideone.com/C1L4YW

这篇关于CTRP派生类中没有名为“ type”的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆