指向方法和指针模板问题,C++

发布于 2024-10-17 00:58:10 字数 981 浏览 2 评论 0原文

有 2 个模板类 A 和 B,有 2 个私有成员 a1、a2 和 b1、b2。

template <typename T>
class A
{
private:
    T a1, a2;

public:
    T getA1 () const {return a1;}
    T getA2 () const {return a2;}

};


template <typename T>
class B
{
private:
    T b1, b2;

public:
    T getB1 () const {return b1;}
    T getB2 () const {return b2;}

};

在 Test 类中,需要 2 个指向 getter 的指针。

class Test
{
  private:
    template <typename T>
    static T ( *getFirst ) ();

    template <typename T>
    static T ( *getSecond ) ();

}


template <typename T>
T ( * Test::getFirst ) ()  =  &A<T>::getA1; //Pointer to getA1, error

template <typename T>
T ( * Test::getSecond ) ()  =  &B<T>::getB2; //Pointer to getB2, error

int main
{
   A <double> a;
   B <double> b;

   double c = a.getFirst + b.getSecond;
}

T 代表基本数据类型...是否可以在没有专门化(即指向类模板成员的指针)的情况下实现此代码,或者那些“指针”应该专门化?感谢您提供任何示例...

There are 2 template classes A and B having 2 private members a1, a2 and b1, b2.

template <typename T>
class A
{
private:
    T a1, a2;

public:
    T getA1 () const {return a1;}
    T getA2 () const {return a2;}

};


template <typename T>
class B
{
private:
    T b1, b2;

public:
    T getB1 () const {return b1;}
    T getB2 () const {return b2;}

};

In the class Test there is a need for 2 pointers pointing to getters.

class Test
{
  private:
    template <typename T>
    static T ( *getFirst ) ();

    template <typename T>
    static T ( *getSecond ) ();

}


template <typename T>
T ( * Test::getFirst ) ()  =  &A<T>::getA1; //Pointer to getA1, error

template <typename T>
T ( * Test::getSecond ) ()  =  &B<T>::getB2; //Pointer to getB2, error

int main
{
   A <double> a;
   B <double> b;

   double c = a.getFirst + b.getSecond;
}

T represents fundamental data types... Is it possible implement this code without specialization (i.e. pointers to class template members) or those "pointers" should be specialized? Thanks for any examples...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浪漫人生路 2024-10-24 00:58:10

你正在做违法的事情。看到这个,

template <typename T>
static T ( *getFirst ) ();

这里你试图定义模板函数指针,这在 C++ 中是非法的。

C++ 标准在 $14/1 中表示,

模板定义一系列
函数

请注意,它不是说“模板定义了一系列函数或函数指针 >”。所以你想要做的是,使用模板定义“函数指针家族”,这是不允许的。


如果你想要函数指针,你可以这样做,

template <class T>
struct A
{
   static T (*FunctionPointer)(); //function pointer
};

struct B
{
   template <class T>
   static T Function(); //static function, not function pointer
};

int (*A<double>::FunctionPointer)() = &B::Function<double>;

更好的选择是:使用函数对象。 :-)

You're doing illegal things. See this,

template <typename T>
static T ( *getFirst ) ();

Here you're trying to define template function pointer which is illegal in C++.

The C++ Standard says in $14/1,

A template defines a family of classes
or functions.

Please note that it does not say "a template defines a family of classes, functions or function pointers". So what you're trying to do is, defining "a family of function pointers" using template, which isn't allowed.


If you want function pointer you can do something like this,

template <class T>
struct A
{
   static T (*FunctionPointer)(); //function pointer
};

struct B
{
   template <class T>
   static T Function(); //static function, not function pointer
};

int (*A<double>::FunctionPointer)() = &B::Function<double>;

Yet better alternative is : use function object. :-)

离鸿 2024-10-24 00:58:10

简而言之,这是不可能的。

首先,不能声明指向模板函数的指针,只能声明指向具体函数的指针。
其次,您尝试声明指向自由函数的指针,但 A::getA1 是带有隐式 this 参数的成员函数,因此语义不匹配。

您可以执行以下操作:

template <typename T>
struct A
{
    static T get() { return T() };
};

template <typename T>
struct Holder
{
    typedef T(A<T>::*F_ptr)();
    static F_ptr f_ptr;
};


template <typename T>
typename Holder<T>::F_ptr Holder<T>::f_ptr  =  &A<T>::get;

将指向模板函数的指针保留为模板类的成员

In short, it's not possible.

First, you cannot declare a pointer to template function, only pointer to a concrete function.
Second, you tried to declare pointer to free function but A::getA1 is a member function with implicit this argument, so semantic doesn't match.

You can do something like this:

template <typename T>
struct A
{
    static T get() { return T() };
};

template <typename T>
struct Holder
{
    typedef T(A<T>::*F_ptr)();
    static F_ptr f_ptr;
};


template <typename T>
typename Holder<T>::F_ptr Holder<T>::f_ptr  =  &A<T>::get;

to keep pointer to template function as a member of template class

梦亿 2024-10-24 00:58:10

该行:

template <typename T>
T (*Test::getFirst)() = &A<T>::getA1; //Pointer to getA1, error

有两个问题:一个是 &A::getA1 的类型为 T (A::*)()const 但 getFirst 的类型输入T (*)()。它们不兼容,因为前者是指向成员函数的指针,而后者则不是。

该行的第二个问题是创建的对象仅在返回类型上有所不同。就像您无法手动声明 double (A::*getFirst)()const 和 char (A::*getFirst)()const 一样,您也无法创建会自动声明它们的模板。

该行:

double c = a.getFirst + b.getSecond;

有其自己的一组问题,这些问题可能与当前的问题相关,也可能无关。

对于这个“不回答”感到抱歉。也许如果您更多地谈论您想要实现的目标,而不是您如何实现它,我们将能够提供帮助。

The line:

template <typename T>
T (*Test::getFirst)() = &A<T>::getA1; //Pointer to getA1, error

Has two problems: One is that &A<T>::getA1 is of type T (A::*)()const but getFirst is of type T (*)(). These are not compatible because the former is a pointer to a member function, while the latter is not.

The second problem with the line is that the objects created would differ only in their return type. Just like you cannot manually declare both double (A::*getFirst)()const and char (A::*getFirst)()const, you also cannot create a template that would automatically declare both of them.

The line:

double c = a.getFirst + b.getSecond;

Has its own set of problems that may or may not relate to the issue at hand.

Sorry for this "non answer." maybe if you talked more about what you are trying to accomplish, rather than how you are trying to accomplish it, we will be able to help.

萌梦深 2024-10-24 00:58:10

您的代码似乎很混乱,所以我不确定我是否真的理解您所要求的内容...这是对您的编译示例的改编。

// This is one template class A with two getters
template <typename T>
class A
{
private:
    T a1, a2;

public:
    T getA1 () const {return a1;}
    T getA2 () const {return a2;}
};

// This is another unrelated template class, with two other getters
template <typename T>
class B
{
private:
    T b1, b2;

public:
    T getB1 () const {return b1;}
    T getB2 () const {return b2;}
};

// These are declarations of generic "getFirst" and "getSecond"
template<typename T1, typename T2>
T1 getFirst(const T2& t);

template<class T1, class T2>
T1 getSecond(const T2& t);

// Here I'm specializing getFirst/getSecond for the A template
template<class X>
double getFirst(const A<X>& a)  { return a.getA1(); }

template<class X>
double getSecond(const A<X>& a) { return a.getA2(); }

// Here I'm doing the same for the B template
template<class X>
double getFirst(const B<X>& b)  { return b.getB1(); }

template<class X>
double getSecond(const B<X>& b) { return b.getB2(); }

// Now I can use getFirst/getSecond with either A or B
int main(int argc, const char *argv[])
{
   A<double> a;
   B<double> b;
   double c = getFirst(a) + getSecond(b);
   return 0;
}

Your code seems quite confused, so I'm not sure I really understood what you are asking for... here is an adaptation of your example that compiles.

// This is one template class A with two getters
template <typename T>
class A
{
private:
    T a1, a2;

public:
    T getA1 () const {return a1;}
    T getA2 () const {return a2;}
};

// This is another unrelated template class, with two other getters
template <typename T>
class B
{
private:
    T b1, b2;

public:
    T getB1 () const {return b1;}
    T getB2 () const {return b2;}
};

// These are declarations of generic "getFirst" and "getSecond"
template<typename T1, typename T2>
T1 getFirst(const T2& t);

template<class T1, class T2>
T1 getSecond(const T2& t);

// Here I'm specializing getFirst/getSecond for the A template
template<class X>
double getFirst(const A<X>& a)  { return a.getA1(); }

template<class X>
double getSecond(const A<X>& a) { return a.getA2(); }

// Here I'm doing the same for the B template
template<class X>
double getFirst(const B<X>& b)  { return b.getB1(); }

template<class X>
double getSecond(const B<X>& b) { return b.getB2(); }

// Now I can use getFirst/getSecond with either A or B
int main(int argc, const char *argv[])
{
   A<double> a;
   B<double> b;
   double c = getFirst(a) + getSecond(b);
   return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文