2

It's an exercise of C++ Primer 5th. I don't know how to solve it?

The problem described as:

Write the declaration for a function that returns a reference to an array of ten strings, without using either a trailing return, decltype, or a type alias.

My codes:

#include <iostream>
#include <string>

std::string (&func(std::string a[])) [10]
{
    return a;
}

int main()
{
    std::string a[10];
    std::string (&b)[10] = func(a);
    for (const auto &c : b)
        std::cout << c << std::endl;
    return 0;
}

compile errors:

e6_36.cc:6:12: error: non-const lvalue reference to type 'std::string [10]' cannot bind to a value of unrelated type 'std::string *' (aka 'basic_string, allocator > *')

return a;

       ^

1 error generated.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Aristotle0
  • 317
  • 2
  • 9
  • Did you check out [this answer](http://stackoverflow.com/a/5399014/1214731)? – tmpearce Jun 10 '14 at 02:37
  • 1
    You already got the return type correct. It's just that the value which you are returning is not of the right type, because your parameter type is wrong. – Benjamin Lindley Jun 10 '14 at 02:44
  • To be clear: the question is just asking for `std::string (&func()) [10];` . That's a function declaration. You're attempting to go further by providing a function definition and giving it some arguments, and that's where you ran into some trouble. – M.M Jun 10 '14 at 03:13
  • I might be getting something wrong, but isn't the question just asking for "std::array& my_func();"? – Viktor Sehr Sep 25 '17 at 23:41

2 Answers2

1

You can pass the array by reference, so you can return it :

std::string (&func(std::string (& a) [10])) [10]
{
    return a;
}

Or to make things clearer, use a typedef for your array of strings:

typedef std::string StrArray[10];

StrArray& func2(StrArray& a) {
   return a;
}

EDIT:

When you did :

std::string (&func(std::string a[])) [10]
{
    return a; // error !
}

The argument a is an array of std::string and decays to a pointer to std::string* , which is passed by value (so, copied): You are asking the compiler to bind a non-const reference (the return type) to a temporary, which is illegal in C++.

quantdev
  • 23,517
  • 5
  • 55
  • 88
  • Your answer is right, but I don't understand why to use a reference in the parameter. Is it because that if I don't use reference, I return a reference to the copy of **a** that is local? – Aristotle0 Jun 10 '14 at 04:20
  • In the erroneous code, the problem is attempt to bind `std::string(&)[10]` to a `std::string *`, which is a type mismatch. It would fail for the same reason even if a const reference were used. – M.M Sep 25 '17 at 03:02
0

string (&func(string (&as)[10]))[10]

  • string (&as)[10] is a reference to an array of 10 string type elements.
  • func(string (&as)[10]) says we can call func whose parameter is a reference to an array of 10 string type elements.
  • (&func(string (&as)[10])) says reference is return.
  • (&func(string (&as)[10]))[10] says that reference yields an array of size 10.
  • string (&func(string (&as)[10]))[10] says that the element type in the array is of string type.
#include <iostream>    
#include <string>    

std::string (&func(std::string(&as)[10]))[10]    
{  
    for (int i = 0; i != 10; ++i) {  
        as[i] = as[i] + " number " + std::to_string(i); //append to string  
    }  
    return as;  
}  

int main()  
{  
    std::string array_str[10];  
    // initialize array with "I am"  
    for (auto &str : array_str) {  
        str = "I am";  
    }  
    // give reference of string[10] to func
    using aStr = std::string[10];   // alias   
    aStr &ref_aStr = func(array_str);
    // print to see results
    for (auto str : ref_aStr) {
        std::cout << str << std::endl;
    }
    return 0;  
}  
Jtaim
  • 1
  • 2