[英]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_cast
上p
):
int main(){
A<int*> a;
const int* p = nullptr;
a.foo(p);
a.bar();
A<int>().foo(10);
}
问题是,据我所知,当A
由int*
模板化时, 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_pointer
, std::remove_pointer
和std::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.