son*_*yao 7 c++ typedef type-conversion conversion-operator language-lawyer
这是一个返回数组引用的转换函数:
struct S {
typedef int int_array_20[20];
operator int_array_20& ();
};
Run Code Online (Sandbox Code Playgroud)
没有可能做同样的事情typedef
吗?我尝试过的:
struct S {
operator int (&()) [10];
};
Run Code Online (Sandbox Code Playgroud)
但克朗抱怨道:
error: C++ requires a type specifier for all declarations
operator int (&()) [10];
~ ^
error: conversion function cannot have any parameters
operator int (&()) [10];
^
error: must use a typedef to declare a conversion to 'int [10]'
error: conversion function cannot convert to an array type
Run Code Online (Sandbox Code Playgroud)
请问:
必须使用typedef来声明转换为'int [10]'
意味着typedef
不可或缺?
编辑
如果typedef
有必要,就不可能像下面那样创建转换函数模板,因为无法定义typedef
模板,是不是?
struct S {
template<typename T, int N>
operator T(&())[N];
};
Run Code Online (Sandbox Code Playgroud)
是的,确实需要我们通过转到cppreference部分用户定义的转换来看到这一点,该转换说:
声明器中不允许使用函数和数组运算符[]或()(因此转换为类型指针等类型需要typedef:见下文).无论typedef如何,conversion-type-id都不能表示数组或函数类型.
我们可以在草案C++标准部分12.3.2
转换函数中找到它,它说:
conversion-type-id不代表函数类型,也不代表数组类型.conversion-function-id中的conversion-type-id是转换声明符最长的序列.[注意:这可以防止声明者运算符*与其表达式对应物之间的歧义.[例如:
Run Code Online (Sandbox Code Playgroud)&ac.operator int*i; // syntax error: // parsed as: &(ac.operator int *)i // not as: &(ac.operator int)*i
*是指针声明符,而不是乘法运算符. - 末端示例] - 尾注]
而conversion-type-id的语法如下:
Run Code Online (Sandbox Code Playgroud)conversion-type-id: type-specifier-seq conversion-declaratoropt conversion-declarator: ptr-operator conversion-declaratoropt
这比一个语法看起来像这样的声明符更受限制:
Run Code Online (Sandbox Code Playgroud)declarator: ptr-declarator noptr-declarator parameters-and-qualifiers trailing-return-type ptr-declarator: noptr-declarator ptr-operator ptr-declarator noptr-declarator: declarator-id attribute-specifier-seqopt noptr-declarator parameters-and-qualifiers noptr-declarator [ constant-expressionopt] attribute-specifier-seqopt ( ptr-declarator )
克里斯提到的一个替代方案是使用身份类:
template <typename T>
struct identity
{
typedef T type;
};
Run Code Online (Sandbox Code Playgroud)
你会用它如下:
operator typename identity<int(&)[10]>::type() ;
Run Code Online (Sandbox Code Playgroud)