在CTRP派生类中没有名为"type"的类型

Gre*_*kel 9 c++ templates non-virtual-interface

我一直在尝试使用奇怪的重复模板模式进行通用的单参数仿函数,并且有两个实现:一个使用模板模板参数工作,另一个我尝试访问接口类中的派生Functor ::类型.在后一个例子中,编译器(gcc 5.4.0)报告

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

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!)
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

R S*_*ahu 5

当行

using Ftype = typename Functor::type;
Run Code Online (Sandbox Code Playgroud)

在基类中处理,定义Functor不可用.因此,你不能使用Functor::type.

解决此限制的一种方法是定义特征类.

// 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
Run Code Online (Sandbox Code Playgroud)

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