C ++支持的类型的表达式语法是什么? [英] What are the expression syntax over types C++ support?

查看:80
本文介绍了C ++支持的类型的表达式语法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有一组整数的模板化类。代码就像

I was working with a templated class which takes a set of integers. The code was like,

template<unsigned... Idx>
struct work{ ... };

然后我意识到,用户可能需要提供一组整数或一系列整数。因此,我几乎不更改语法以支持实例化,例如,

Then I realized, user may need to provide either a set of integers, or a range of integers. So, I changed the syntax little to support instantiation like,

work<indexes<1,3,2,4> > //instead of work<1,3,2,4>
work<span<1,4> > //same as work<1,2,3,4> 

而在C ++中,我们有大量的运算符,可用于构造外来表达模板(再说 boost :: xpressive boost :: lambda boost :: spirit 等),类型操作的可能性要少得多。

While, in C++ we have large number of operators, and can be used to formulate exotic expression templates (say boost::xpressive, boost::lambda, boost::spirit etc) , possibilities for type manipulation is much less.

在Sean Parent的boostcon主旨演讲中,他指出仍然不能写 pair< int> 表示一对整数。在我的Persinal库中,我做了类似 tuple< int [3]> 的语法来表示3个整数的元组,而不是编写类型为3 int的元组参数,请注意,我不会在任何地方写原始数组作为元组参数! (请注意: std :: array< int,3> 与上述内容不同,因为在 tuple <时std :: array无法存储引用/ code>可以说 std :: tuple< int&,int&,int& 是可能的)

In a boostcon keynote by Sean Parent, he noted one still can not write pair<int> to denote a pair of integers. In my persinal library, I made a syntax like tuple<int[3]> to denote a tuple of 3 integers, instead of writing a tuple with 3 int in the type arguments, noting that I do not write a raw array as tuple argument anywhere! (note: std::array<int,3> is not same as the above, as std::array can not store references while tuple can, say std::tuple<int&,int&,int&> is possible)

那么,我想知道我可以编写哪种类型的类型表达式?

So, I want to know what are the different kind of "type expressions" I can write?

到目前为止,我可以想到对象类型,函数类型,引用类型,是否带有cv修饰符,指针等。例如

So far I can think of object type, function type, reference type, with/without cv modifiers, pointers etc. e.g

    template<class T>
    struct tpl;

    using t1 = tpl<int>;//simple type
    //function (can have function pointer/reference also) 
    // e.g. void(*)(int,float) or void(&)(int,float)
    using t2 = tpl<void(int,float)>;
    //array can have pointer / reference also
    //e.g. int(&)[4] or int (*)[4]
    using t3 = tpl<int[4]>;
    using t4 = tpl<int[]>;
    using t5 = tpl<int const>;//with cv modifiers
    using t6 = tpl<int*>;//with pointer
    using t7 = tpl<int&>;//with reference (& or &&)
    using t8 = tpl<tpl<int> >; //template itself
    using t9 = tpl<void(...)>; //variadic functions
    using t10 = tpl<R C::*>; //pointer to member

的指针,但我相信还有很多可能。

But I believe, many more are possible.

注意:这个问题纯粹是理论上的,我只想知道我可以在<>中作为类型参数写的各种语法,而不是可读性/道德性。方面,甚至如何实现我给出的一些示例,例如工作类。

NOTE: This question is purely theoretical, I just want to know all kinds of syntax I can write inside <> as type argument, and not about the readability/morality aspect of it, or even how can I implement some of the examples I had given, like the work class.

推荐答案

可以使用声明符语法构造复合类型-可以在 [dcl.decl]中找到 code>。

Compound types can be constructed using the declarator syntax - found in [dcl.decl].

此语法的基础是六个基本结构,其中任何 T 都可以替换为列表中的任何其他构造。 [以下,(T)表示零个或多个类型(可能以'...'结尾)的列表,而< T> 表示一种或多种类型的列表。]

Underlying this syntax are six fundamental constructs, within which any T can be substituted by any of the other constructs in the list. [In the following, (T) represents a list of zero or more types (which may end in '...'), and <T> represents a list of one or more types.]

T // T
T* // pointer to T
T& // reference to T
T[n] // array of size 'n' of T
T C::* // pointer to C::member of type T
T (T) // function taking '(T)' and returning T

EDIT :可以将类模板专业化的类型替换为任何 T

EDIT: The type of a class template specialization can be subsituted for any T:

C<T> // specialization of class template C with arguments '<T>'

对类模板C进行特殊化产生具有特殊意义的构造:

There are combinations of the above that produce constructs which have special significance:

T (*)(T) // pointer to function taking '(T)' and returning T
T (C::*)(T) // pointer to C::member-function taking '(T)' and returning T

另外,某些构造可能具有简历资格:

Additionally, some of the constructs may be cv-qualified:

const T // const T
T* const // const pointer to T
T C::* const // const pointer to C::member of type T

并非所有组合都产生有效的类型。根据 [basic.compound] ,只能使用以下组合:

Not all of the combinations result in valid types. According to [basic.compound], only the following combinations can be used:


可以通过以下方式构造化合物类型:

Compound types can be constructed in the following ways:


  • 给定类型的对象数组

  • 具有给定类型的参数并返回void或给定类型的引用或对象的函数

  • 指向给定类型的void或对象或函数(包括类的静态成员)的指针

  • 对给定类型的对象或函数的引用

  • 指向非静态类成员的指针,这些成员标识给定对象内给定类型的成员class

  • arrays of objects of a given type
  • functions, which have parameters of given types and return void or references or objects of a given type
  • pointers to void or objects or functions (including static members of classes) of a given type
  • references to objects or functions of a given type
  • pointers to non-static class members, which identify members of a given type within objects of a given class

提到了其他限制:

[dcl.ptr] 没有指向引用的指针

[dcl.ref] 应该没有对引用的引用,没有引用的数组,也没有指向re的指针引用

[dcl.ref] There shall be no references to references, no arrays of references, and no pointers to references

[dcl.mptr] 指向成员的指针不得指向...具有引用类型的成员,或
cv void。

[dcl.mptr] A pointer to member shall not point to ... a member with reference type, or "cv void."

[dcl.fct] 参数列表(无效)等效于空参数列表。除此特殊情况外,void不得为参数类型。 ...如果参数的类型包括指向T的未知边界数组的指针或将
指向T的未知边界数组的指针形式的类型,则程序格式错误。函数不得具有数组或函数类型的返回类型。

[dcl.fct] The parameter list (void) is equivalent to the empty parameter list. Except for this special case, void shall not be a parameter type. ... If the type of a parameter includes a type of the form "pointer to array of unknown bound of T" or "reference to array of unknown bound of T," the program is ill-formed. Functions shall not have a return type of type array or function.

某些可能的构造不能用作模板参数。当您明确指定一组模板参数时,编译器必须检查模板参数是否可以代替模板参数,而不会导致无效类型。根据 [temp.deduct] \2 ,以下构造构成无效类型:

Some of the possible constructs cannot be used as template-arguments. When you explicitly specify a set of template-arguments, the compiler must check that the template-arguments can be substituted for the template-parameters without resulting in an 'invalid type'. According to [temp.deduct]\2, the following constructs constitute invalid types:


类型推导可能由于以下原因而失败:

Type deduction may fail for the following reasons:


  • 尝试创建具有无效元素类型的数组,函数类型或引用类型,或尝试创建大小为零或负数的数组。

  • Attempting to create an array with an element type that is void, a function type, or a reference type, or attempting to create an array with a size that is zero or negative.

template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); // invalid array


  • 试图在限定条件中使用不是类类型的类型

  • Attempting to use a type that is not a class type in a qualified name.

    template <class T> int f(typename T::B*);
    int i = f<int>(0);
    


  • 试图在限定名称的限定词部分使用一种类型,该名称在该类型不包含指定的成员,或者如果指定的成员不是需要该类型的类型。

  • Attempting to use a type in the qualifier portion of a qualified name that names a type when that type does not contain the specified member, or if the specified member is not a type where a type is required.

    template <class T> int f(typename T::B*);
    struct A {};
    struct C { int B; };
    int i = f<A>(0);
    int j = f<C>(0);
    


  • 尝试创建指向引用类型的指针。

  • Attempting to create a pointer to reference type.

    试图创建对引用类型的引用或对void的引用。

    Attempting to create a reference to a reference type or a reference to void.

    试图创建指向成员的指针

    Attempting to create "pointer to member of T" when T is not a class type.

    template <class T> int f(int T::*);
    int i = f<int>(0);
    


  • 尝试在模板参数表达式或用于

  • Attempting to perform an invalid conversion in either a template argument expression, or an expression used in the function declaration.

    template <class T, T*> int f(int);
    int i2 = f<int,1>(0); // can’t conv 1 to int*
    


  • 试图在其中创建函数类型一个参数的类型为void。

  • Attempting to create a function type in which a parameter has a type of void.

    编辑:这基于C ++ 03,但也适用于C ++ 11(添加了右值引用类型)

    This is based on C++03, but also applies to C++11 (which adds rvalue reference types)

    这篇关于C ++支持的类型的表达式语法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆