【问题标题】:Is it possible to declare the conversion function returning array reference without the typedef?是否可以在没有 typedef 的情况下声明返回数组引用的转换函数?
【发布时间】:2014-09-10 05:52:04
【问题描述】:

这是一个返回数组引用的转换函数:

struct S { 
    typedef int int_array_20[20];
    operator int_array_20& ();
};

没有typedef 也可以做同样的事情吗?我试过的:

struct S { 
    operator int (&()) [10];
};

但是clang抱怨:

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

做:

必须使用 typedef 来声明转换为 'int [10]'

意思是typedef是必不可少的吗?

编辑
如果typedef是必要的,就不可能创建如下的转换函数模板,因为无法定义typedef模板,对吧?

struct S { 
    template<typename T, int N>
    operator T(&())[N];
};

【问题讨论】:

  • 是的,你必须使用typedef,因为它清楚地告诉你。
  • 我现在真的不想跟随这条链,但从这里开始:i.imgur.com/1eqfyiW.png

标签: c++ type-conversion typedef language-lawyer conversion-operator


【解决方案1】:

是的,这确实是必需的,我们可以通过转到 cppreference 部分 user-defined conversion 看到这一点:

函数和数组运算符 [] 或 () 不允许在 声明符(因此转换为指向数组的指针等类型需要 typedef:见下文)。不管typedef,conversion-type-id 不能表示数组或函数类型。

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

conversion-type-id 不应代表函数类型或 数组类型。转换函数 ID 中的转换类型 ID 是 最长可能的转换声明器序列。 [注:这 防止声明符运算符 * 与其 表达对应物。 [ 例子:

&ac.operator int*i; // syntax error:
                    // parsed as: &(ac.operator int *)i
                    // not as: &(ac.operator int)*i

* 是指针声明符,而不是乘法运算符。 —结束示例] —结束说明]

conversion-type-id的语法如下:

conversion-type-id:
  type-specifier-seq conversion-declaratoropt
conversion-declarator:
  ptr-operator conversion-declaratoropt

声明符 更受限制,其语法如下所示:

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;
};

您可以按如下方式使用它:

operator typename identity<int(&)[10]>::type() ;

【讨论】:

  • 我采用标准不涵盖对数组的引用。
  • 感谢您的确认。你能看到我对帖子的编辑吗?这样的转换函数模板就不能创建吗?
  • @songyuanyao,我想用某种id模板等,你可以做operator typename id&lt;T(&amp;)[N]&gt;::type()(或者在C++11中更好一点)。
  • @chris 使用using 别名会更好。
  • @0x499602D2,是的,那将是 C++11 位。我不知道为什么,但我认为这个问题有一些暗示它不是 C++11 的东西,但这只是我得到随机的概念。
猜你喜欢
  • 1970-01-01
  • 2015-08-24
  • 2015-06-28
  • 2017-03-22
  • 2011-07-02
  • 1970-01-01
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多