繁体   English   中英

将const指针参数传递给模板类的成员函数

[英]Passing a const pointer argument to a member function of a template class

考虑以下类别:

template<typename T> class A{
public:
    virtual void foo(const T& v){ m_v = v + 1; }    
    T& bar(){ return m_v;}
    T m_v;
    // ... other member functions/variables ...
};

它如何能够被修改,使得下面的代码工作(无,如果可能的话具有向一个const_castp ):

int main(){
    A<int*> a;
    const int* p = nullptr;
    a.foo(p);
    a.bar();

    A<int>().foo(10);
}

问题是,据我所知,当Aint*模板化时, foo方法的签名变成foo(int* const&) 我们想拥有的东西应该像foo(const int* const&)

到目前为止,我考虑过为A成员添加一个foo成员函数的专门实现,该实现由类声明之外的指针类型进行模板化(就像对A<int>::foo进行专门化那样),但是编译器无法解析该函数定义原型到声明的方法。

template<typename T>
void A<T*>::foo(const T* const& ){}

gcc抱怨这是invalid use of incomplete type 'class A<T*>'invalid use of incomplete type 'class A<T*>'

我还考虑过为指针类型的整个类添加部分专门化,它定义了一个额外的成员重载foo ,该foo接受const T* ,但是我不知道如何重用基本模板中的其余代码(即,不重复所有其他函数的声明和定义,例如bar )。 有没有一种方法可以从指针局部特化中引用基本模板类,以进行继承或具有将调用转发到的成员? 这篇文章提供了通过增加一个额外的虚拟模板参数的解决方案。有没有办法来规避呢?)。

最后,我还考虑过使用enable_if<is_pointer<T>::value, void>::type foo(const PointedToType*); 当模板参数是指针时,如何在foo方法中添加额外的重载,但是如何从T获取PointedToType (当已知T是指针类型时)?

在我看来,您只需要为foo的参数类型指定一个特征即可:

template <typename T>
struct arg_type { using type = T const&; };

template <typename T>
struct arg_type<T*> { using type = T const*; };

template <typename T>
using arg_type_t = typename arg_type<T>::type;

因此使用:

virtual void foo(arg_type_t<T> arg ) {}

我不确定这是否是您想要的,但是您可以结合使用std::is_pointerstd::remove_pointerstd::conditional来构造所需的参数类型。 但是,我不知道您将如何编写函数主体以使用该参数来执行有用的操作。

#include <type_traits>

template <typename T>
struct A
{
  template <
    typename U = T,
    typename ArgT = std::conditional_t<
      std::is_pointer<U>::value,
      const std::remove_pointer_t<U> *,
      U>
  >
  void
  foo(const ArgT&)
  {
    // ...
  }
};

我在这里使用C ++ 14类型的元函数。 如果您不能使用C ++ 14, std::fancy_t< … >替换为typename std::fancy< … >::type

现在有效:

int
main()
{
  {
    A<int *> a {};
    const int * p {};
    a.foo(p);
  }
  {
    A<int> a {};
    const int i {};
    a.foo(i);
  }
}

您可以使用const模板参数定义a ,即A<const int*> a; 那行得通。

template<typename T> class A{
public:
    void foo(const T &v){ m = v; }
    void bar(T &v){ v = m; }
    T m;
    // ... other member functions/variables ...
};

int main(){
    A<const int*> a;
    const int* p = nullptr;
    a.foo(p);
    a.bar(p);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM