Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the C++14 standard say regarding auto as argument type

Tags:

c++

c++14

auto

Lets take a look at the following code below:

#include <iostream>

class Test
{
private:
    int x;
public:
    Test(int _x) :
        x(_x)
    {
        std::cout << "Im being constructed" << std::endl;
    }

    int getx()
    {
        return this->x;
    }

    friend std::ostream& operator<<(std::ostream& os, Test& other)
    {
        os << other.getx();
        return os;
    }
};

auto func(auto x)
{
    std::cout << x << std::endl;
    return x.getx();
}

int main()
{
    auto y = func(20);

    return 0;
}

How does the compiler decide if (20) should be an int or Test object? The constructor for Test is not explicit so what does the standard say about it?

like image 911
Mamma Avatar asked Nov 09 '15 10:11

Mamma


2 Answers

So although gcc allows auto as a parameter in functions this is not part of C++14 but part of concepts-lite which may become part of C++1z according to Herb Sutter's last trip report.

I believe gcc allows this as an extension and if we compile your program using -pedantic gcc will warn:

 warning: ISO C++ forbids use of 'auto' in parameter declaration [-Wpedantic]
 auto func(auto x)
           ^

So from concept-lite proposal we can see that:

auto func(auto x)
{
    std::cout << x << std::endl;
    return x.getx();
}

is equivalent to:

template <typename T1>
auto func(T1 x)
{
    std::cout << x << std::endl;
    return x.getx();
}

and therefore x will be deduced as int. The compiler will rightfully give you an error like the following one from gcc (see it live):

error: request for member 'getx' in 'x', which is of non-class type 'int'
     return x.getx();
                   ^

This is covered in the proposal section 5.1.1 [dcl.fct]:

The use of auto or a concept-name in the parameter-declaration-clause shall be interpreted as the use of a type-parameter having the same constraints and the named concept. [ Note: The exact mechanism for achieving this is unspecified. —end note ] [ Example: The generic function declared below

auto f(auto x, const Regular& y);

Is equivalent to the following declaration

template<typename T1, Regular T2>
  auto f(T1 x, const T2&);

—end example ]

like image 162
Shafik Yaghmour Avatar answered Oct 16 '22 12:10

Shafik Yaghmour


The rules for auto as argument type are the same as for template arguments.

auto func(auto x) is equivalent to template<typename T> auto func(T x)

I am no lawyer to quote the standard on the specific rules, though.

like image 23
user362515 Avatar answered Oct 16 '22 13:10

user362515