Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to declare the conversion function returning array reference without the typedef?

Here's a conversion function returning an array reference:

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

Is it possible to do the same thing without typedef? What I've tried:

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

but clang complains:

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

Does:

must use a typedef to declare a conversion to 'int [10]'

mean typedef is indispensable?

EDIT
If typedef is necessary, it's impossible to create a conversion function template like the following, because couldn't define a typedef template, is it right?

struct S { 
    template<typename T, int N>
    operator T(&())[N];
};
like image 301
songyuanyao Avatar asked Jul 19 '14 02:07

songyuanyao


People also ask

How do you return an array as a reference?

Return Array from Functions in C++ C++ does not allow to return an entire array as an argument to a function. However, you can return a pointer to an array by specifying the array's name without an index.

What is the return type of conversion function?

1. What is the return type of the conversion operator? Explanation: Conversion operator doesn't have any return type not even void.

How do you write a conversion function in C++?

You can define a member function of a class, called a conversion function, that converts from the type of its class to another specified type. All three statements in function f(Y) use the conversion function Y::operator int() .

Can a function return an array C++?

Using a Structure in C++ We can also make a function return an array by declaring it inside a structure in C++.


1 Answers

Yes, this is indeed required we can see this by going to the cppreference section user-defined conversion which says:

Function and array operators [] or () are not allowed in the declarator (thus conversion to types such as pointer to array requires a typedef: see below). Regardless of typedef, conversion-type-id cannot represent an array or a function type.

We can find this in the draft C++ standard section 12.3.2 Conversion functions which says:

The conversion-type-id shall not represent a function type nor an array type. The conversion-type-id in a conversion-function-id is the longest possible sequence of conversion-declarators. [ Note: This prevents ambiguities between the declarator operator * and its expression counterparts. [ Example:

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

The * is the pointer declarator and not the multiplication operator. —end example ] —end note ]

and the grammar for conversion-type-id is as follows:

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

which is more restricted then a declarator whose grammar looks like this:

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 )

One alternative as chris mentioned was to use an identity class:

template <typename T>
struct identity
{
    typedef T type;
};

you would use it as follows:

operator typename identity<int(&)[10]>::type() ;
like image 81
Shafik Yaghmour Avatar answered Sep 28 '22 04:09

Shafik Yaghmour