Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typename lookup of return parameter

Tags:

c++

I was recently asked by a student about a compile issue. The answer was quite simple but right now I am struggling about the reason. A simple example:

#include <iostream>
#include <vector>

struct MyStruct
{
    typedef std::vector<int> MyIntVector;

    MyIntVector CopyVector(MyIntVector const& vector);
};


MyStruct::MyIntVector MyStruct::CopyVector(MyIntVector const& vector)
^^^^^^^^
{
    MyIntVector vec;
    return vec;
}

int main(int /*argc*/, char** /*argv*/)
{
    MyStruct st;
}

To be valid c++ code the return parameter has to be fully qualified. So much to the answer and to make the compiler/student happy.

But why has the return value to be qualified with the class and the parameter to the function not?

I always did this and I know that it has to do with the ADL lookup, but now that I was asked I searching for a better answer.
Can anyone give a me reference to the spec or a hint where I can find some more information?

like image 342
mkaes Avatar asked Apr 14 '11 11:04

mkaes


2 Answers

The structure of the grammar is such that the return type is independant of what is declared and it is possible to declare (but not define) several things with the same type. This is valid C++:

int f(int), g(int);

so having the precise scope of the declared objects influencing the lookup for the type would be problematic. In

id1 ns1::f(int), ns2::g(int);

where would id1 be looked up?

One could have added special rules to use in function definition (there can be only one function definition -- so there would be no ambiguity --, but can be several object one), but I'm not sure the possibility has been examined, and I think the added complication would not be compensated by the advantage.

like image 156
AProgrammer Avatar answered Nov 02 '22 15:11

AProgrammer


To proceed with parsing, the compiler needs to figure out what is a typename and what is not.

The only thing that can occur at namespace scope is a declaration, and most C++ declarations begin with a typename, but this is not the case in C. Putting a stray, undefined identifier at toplevel scope in a C program declares it to be an int with static visibility.

Regardless of the possibility of compiling a program, it also makes the parser much simpler if it can proceed from beginning to end without queuing up tokens for later identification within the context of the class.

C++11 solves the problem with trailing-return-type syntax:

auto MyStruct::CopyVector(MyIntVector const& vector) -> MyIntVector {
like image 20
Potatoswatter Avatar answered Nov 02 '22 13:11

Potatoswatter