简体   繁体   English

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

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

Consider the following 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 ...
};

How can it be modified such that the following code works (without, if possible having to to a const_cast on p ): 它如何能够被修改,使得下面的代码工作(无,如果可能的话具有向一个const_castp ):

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

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

The problem is that the signature of the foo method, when A is templated by int* becomes, as far as I can tell, foo(int* const&) . 问题是,据我所知,当Aint*模板化时, foo方法的签名变成foo(int* const&) What we would like to have would be something like foo(const int* const&) . 我们想拥有的东西应该像foo(const int* const&)

Until now, I considered adding a specialized implementation of the foo member function for A templated by pointer types outside the class declaration (as one would do for specializing A<int>::foo ), but the compiler is not able to resolve the function definition prototype to the declared method. 到目前为止,我考虑过为A成员添加一个foo成员函数的专门实现,该实现由类声明之外的指针类型进行模板化(就像对A<int>::foo进行专门化那样),但是编译器无法解析该函数定义原型到声明的方法。

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

gcc complains that it's an invalid use of incomplete type 'class A<T*>' gcc抱怨这是invalid use of incomplete type 'class A<T*>'invalid use of incomplete type 'class A<T*>'

I've also considered adding a partial specialization for the whole class for pointer types which defines an extra member overloading foo that takes in a const T* , but I couldn't figure out how to reuse the rest of the code in the base template (ie without duplicating the declarations and definitions for all the other functions, eg bar ). 我还考虑过为指针类型的整个类添加部分专门化,它定义了一个额外的成员重载foo ,该foo接受const T* ,但是我不知道如何重用基本模板中的其余代码(即,不重复所有其他函数的声明和定义,例如bar )。 Is there a way to reference the base template class from the pointer partial specialization, either for inheritance or for having a member to which to forward calls? 有没有一种方法可以从指针局部特化中引用基本模板类,以进行继承或具有将调用转发到的成员? ( This post provides a solution by adding an extra dummy template argument. Is there a way to circumvent this?). 这篇文章提供了通过增加一个额外的虚拟模板参数的解决方案。有没有办法来规避呢?)。

Finally, I've also thought about using enable_if<is_pointer<T>::value, void>::type foo(const PointedToType*); 最后,我还考虑过使用enable_if<is_pointer<T>::value, void>::type foo(const PointedToType*); to add an extra overload to the foo method when the template parameter is a pointer, but how can one get PointedToType from T (when it is known that T is a pointer type)? 当模板参数是指针时,如何在foo方法中添加额外的重载,但是如何从T获取PointedToType (当已知T是指针类型时)?

Seems to me that you just need a trait for what the argument type of foo should be: 在我看来,您只需要为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;

To be used thusly: 因此使用:

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

I'm not sure if this is what you want but you could use a combination of std::is_pointer , std::remove_pointer and std::conditional to construct the argument type you want. 我不确定这是否是您想要的,但是您可以结合使用std::is_pointerstd::remove_pointerstd::conditional来构造所需的参数类型。 I don't know how you would write the function body to do useful things with that argument, however. 但是,我不知道您将如何编写函数主体以使用该参数来执行有用的操作。

#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&)
  {
    // ...
  }
};

I'm using the C++14 type meta-functions here. 我在这里使用C ++ 14类型的元函数。 If you cannot use C++14, replace std::fancy_t< … > with typename std::fancy< … >::type . 如果您不能使用C ++ 14, std::fancy_t< … >替换为typename std::fancy< … >::type

The following is now valid: 现在有效:

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

You could just define a with a const template argument, ie, A<const int*> a; 您可以使用const模板参数定义a ,即A<const int*> a; . That would work. 那行得通。

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.

相关问题 将指针传递给任何成员函数作为类模板参数 - Passing pointer to any member function as class template argument 将指向成员函数参数的指针传递给模板参数 - Passing pointer to member function parameter into template argument 将成员 function 指针作为参数传递给模板方法 - Passing a member function pointer as an argument to a template method C ++-错误地插入将带有const参数的函数指针传递给模板类 - C++ - Passing a function pointer taking const argument to a template class is wrongly interpeted 将指针传递给成员函数作为模板参数。 为什么这样做? - Passing a pointer to a member function as a template argument. Why does this work? 为什么声明顺序对于将成员函数指针作为模板参数传递很重要? - Why is declaration order important for passing a member function pointer as a template argument? 从指向指向const和非const版本的成员函数的指针的模板参数推导 - Template argument deduction from pointer to member function with const and non-const versions 将成员 Function 指针传递到模板中 - Passing Member Function Pointer into a Template 将成员 function 作为模板参数传递 - Passing a member function as template argument 将智能指针传递给模板类成员函数时的编译错误 - Compilation Error on passing smart pointer to a template class member function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM