具有重复名称的类模板?

时间:2012-02-27 17:31:44

标签: c++ templates

是否可以定义两个具有相同名称的不同模板(按模板参数数量)?

这就是我想要做的事情:

namespace MyNamespace
{

template<class TRet>
class FunctionObject
{
    typedef typename TRet ReturnType;
    virtual ReturnType const operator()() const = 0;
};


template<class TRet, class TArg0>
class FunctionObject
{
    typedef typename TRet ReturnType;
    typedef typename TArg0 FirstArgumentType;
    virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};

}

我在第二个FunctionObject结构定义的右括号末尾提到了太多模板参数的错误。

我知道这可以在C#中完成,但对C ++不确定。有人可以在这里说清楚吗?

4 个答案:

答案 0 :(得分:11)

我认为部分专业化可以解决问题:

namespace MyNamespace {

  template<class TRet, class TArg0>
  class FunctionObject
  {
      typedef typename TRet ReturnType;
      typedef typename TArg0 FirstArgumentType;
      virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
  };

  template<class TRet>
  class FunctionObject<TRet,void>
  {
      typedef typename TRet ReturnType;
      virtual ReturnType const operator()() const = 0;
  };

}

您也可以从包含多个参数的主模板开始。

我认为C ++ 11它的可变参数模板允许它更加漂亮,但我没有时间玩这个,所以我最好把它留给别人展示。

答案 1 :(得分:6)

显示sbi建议的可变参数模板解决方案:

namespace MyNamespace {

  template<typename...> FunctionObject;

  template<class TRet, class TArg0>
  class FunctionObject<TRet,TArg0>
  {
      typedef typename TRet ReturnType;
      typedef typename TArg0 FirstArgumentType;
      virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
  };

  template<class TRet>
  class FunctionObject<TRet>
  {
      typedef typename TRet ReturnType;
      virtual ReturnType const operator()() const = 0;
  };

}

现在您可以按照您喜欢的顺序添加特化,而无需修改其他模板(除非模板参数的数量/类型冲突)。

答案 2 :(得分:5)

我认为您可以使用一个类模板,为第二个模板参数提供默认类型参数:

struct null_type {};

template<class TRet, class TArg0 = null_type>
class FunctionObject
{
    typedef typename TRet ReturnType;
    typedef typename TArg0 FirstArgumentType;

    //both functions here
    virtual ReturnType const operator()() const = 0;

    virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};

答案 3 :(得分:1)

我相信像这样的东西也会起作用,但是单独的课程可能不是你想要的:

   namespace MyNamespace
   {

      class AbstractFunctionObject
      {
         //shared functionality here
      };

      template<class TRet>
      class ConcreteFunctionObjectA : AbstractFunctionObject
      {
         typedef typename TRet ReturnType;
         virtual ReturnType const operator()() const = 0;
      };


      template<class TRet, class TArg0>
      class ConcreteFunctionObjectB : AbstractFunctionObject
      {
         typedef typename TRet ReturnType;
         typedef typename TArg0 FirstArgumentType;
         virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
      };

   }