C++模板奇怪的语法让我烦恼
C++ Template weird syntax annoying me
这是编译和运行正常的完整代码:
# include <iostream>
using namespace std;
template<class T> class A { };
template<int i> class B { };
class C {
public:
int x;
};
class D {
public:
C y;
int z;
};
template<class T> void f (T) { cout << "T" << endl; };
template<class T> void f1(const T) { cout << "const T" << endl; };
temlate<class T> void f2(volatile T) { cout << "volatile T" << endl; };
template<class T> void g (T*) { cout << "T*" << endl; };
template<class T> void g (T&) { cout << "T&" << endl; };
template<class T> void g1(T[10]) { cout << "T[10]" << endl;};
template<class T> void h1(A<T>) { cout << "A<T>" << endl; };
void test_1() {
A<char> a;
C c;
f(c); f1(c); f2(c);
g(c); g(&c); g1(&c);
h1(a);
}
template<class T> void j(C(*)(T)) { cout << "C(*) (T)" << endl; };
template<class T> void j(T(*)()) { cout << "T(*) ()" << endl; }
template<class T, class U> void j(T(*)(U)) { cout << "T(*) (U)" << endl; };
void test_2() {
C (*c_pfunct1)(int);
C (*c_pfunct2)(void);
int (*c_pfunct3)(int);
j(c_pfunct1);
j(c_pfunct2);
j(c_pfunct3);
}
template<class T> void k(T C::*) { cout << "T C::*" << endl; };
template<class T> void k(C T::*) { cout << "C T::*" << endl; };
template<class T, class U> void k(T U::*) { cout << "T U::*" << endl; };
void test_3() {
k(&C::x);
k(&D::y);
k(&D::z);
}
template<class T> void m(T (C::*)() )
{ cout << "T (C::*)()" << endl; };
template<class T> void m(C (T::*)() )
{ cout << "C (T::*)()" << endl; };
template<class T> void m(D (C::*)(T))
{ cout << "D (C::*)(T)" << endl; };
template<class T, class U> void m(C (T::*)(U))
{ cout << "C (T::*)(U)" << endl; };
template<class T, class U> void m(T (C::*)(U))
{ cout << "T (C::*)(U)" << endl; };
template<class T, class U> void m(T (U::*)() )
{ cout << "T (U::*)()" << endl; };
template<class T, class U, class V> void m(T (U::*)(V))
{
cout << "T (U::*)(V)" << endl; };
void test_4() {
int (C::*f_membp1)(void);
C (D::*f_membp2)(void);
D (C::*f_membp3)(int);
m(f_membp1);
m(f_membp2);
m(f_membp3);
C (D::*f_membp4)(int);
int (C::*f_membp5)(int);
int (D::*f_membp6)(void);
m(f_membp4);
m(f_membp5);
m(f_membp6);
int (D::*f_membp7)(int);
m(f_membp7);
}
template<int i> void n(C[10][i]) { cout << "E[10][i]" << endl; };
template<int i> void n(B<i>) { cout << "B<i>" << endl; };
void test_5() {
C array[10][20];
n(array);
B<20> b;
n(b);
}
template<template<class> class TT, class T> void p1(TT<T>)
{ cout << "TT<T>" << endl; };
template<template<int> class TT, int i> void p2(TT<i>)
{ cout << "TT<i>" << endl; };
template<template<class> class TT> void p3(TT<C>)
{ cout << "TT<C>" << endl; };
void test_6() {
A<char> a;
B<20> b;
A<C> c;
p1(a);
p2(b);
p3(c);
}
int main() { test_1(); test_2(); test_3(); test_4(); test_5(); test_6(); }
我的生活和大脑中所有问题的原因是:test_3()
便于阅读的相关代码:
class C {
public:
int x;
};
template<class T> void k(T C::*) { cout << "T C::*" << endl; };
template<class T> void k(C T::*) { cout << "C T::*" << endl; };
template<class T, class U> void k(T U::*) { cout << "T U::*" << endl; };
void test_3() {
k(&C::x);
k(&D::y);
k(&D::z);
}
这段代码最让我烦恼:
template<class T> void k(T C::*)
我的意思是那是什么语法以及它是如何正常工作的。为什么我们需要在C::*
之前T
,或者在T::*
反之亦然之前C
。请帮助我,有人告诉我为什么这种语法如此奇怪以及它是如何工作的。
我是C++新手,在 C#、C 和 OOP 方面有很好的经验。请解释语法和任何替代方法/语法,以更简洁的方式编写上述代码行(如果有的话)。提前谢谢你。
T C::*
声明一个指针,指向类C
中具有T
类型的任何成员(其中T
是模板参数)。该参数没有名称,因此不能在函数中使用。它仅用于过载分辨率。C T::*
和T U::*
也是如此.
它工作的原因可以从实例中看出:
k(&C::x);
这将解析为第一次重载,并且T
将被推断为具有int
类型,因为C::x
的类型是int
。
k(&D::y);
这将解析为第二个重载,因为D::y
的类型为C
。T
将被推断为具有类型D
。
k(&D::z);
这将解析为第三次重载。T
将被推断为具有类型D
,U
将被推断为具有类型int
,因为D::z
是int
类型。
总而言之,我想说这个例子可能是为了混淆人们。如果它的意思是作为一个教程,它可以做更好的命名和一些注释。
看起来该程序演示了各种过载解决情况。这只是练习语法。
T C::*
声明一个对象,该对象引用类型为T
的类C
的成员。若要引用类的成员,需要类的类型和成员的类型。声明中的::
运算符对应于初始化中使用的运算符:
T C:: *x = & C::q;
这里*
指针声明符匹配地址运算符&
,类似于声明和初始化指针T *y = & r;
。引用类成员的对象称为指向成员的指针,因为它看起来像语法中的指针。(但在引擎盖下,它根本不是一个指针。
指向成员的指针很少使用,在更熟悉C++之前,您可以安全地忽略它们。
这与模板没有任何特别关系,程序只是使用指向成员的指针,因为它涉及两种底层类型T
和C
,模板重载解析根据签名中的 T 和 C 与参数类型的 T 和 C 部分匹配的具体程度来选择其中一个函数。
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 单独定义模板化嵌套类方法的正确语法
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 为什么我会收到错误 C2143 语法错误:缺少"*"之前的';'?
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 使用基类指针调用基类的值构造函数的语法是什么?
- 很好的语法来获取对向量/数组数据的大小引用?
- C++语法运算符功能?
- C++使用 rand 定义函数语法
- 什么文件可以修改 atom 的C++语法?
- 创建模板嵌套类实例的语法?
- 最烦人的解析甚至更令人烦恼
- C++模板奇怪的语法让我烦恼