是否可以在没有typedef的情况下声明转换函数返回数组引用?

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)

Sha*_*our 6

是的,确实需要我们通过转到cppreference部分用户定义的转换来看到这一点,该转换说:

声明器中不允许使用函数和数组运算符[]或()(因此转换为类型指针等类型需要typedef:见下文).无论typedef如何,conversion-type-id都不能表示数组或函数类型.

我们可以在草案C++标准部分12.3.2 转换函数中找到它,它说:

conversion-type-id不代表函数类型,也不代表数组类型.conversion-function-id中的conversion-type-id是转换声明符最长的序列.[注意:这可以防止声明者运算符*与其表达式对应物之间的歧义.[例如:

&ac.operator int*i; // syntax error:
                    // parsed as: &(ac.operator int *)i
                    // not as: &(ac.operator int)*i
Run Code Online (Sandbox Code Playgroud)

*是指针声明符,而不是乘法运算符. - 末端示例] - 尾注]

conversion-type-id的语法如下:

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 )
Run Code Online (Sandbox Code Playgroud)

克里斯提到的一个替代方案是使用身份类:

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)

  • @songyuanyao,我想用某种`id`模板等,你可以做`operator typename id <T(&)[N]> :: type()`(或者在C++ 11中好一点). (2认同)