I came across this weird function syntax:
const int n = 3;
auto (*f3)(int n)->int (*)[n]; //error: parameter 'n' as array bound
while reading about scope at this page at cppreference.com.
Although the second statement is an error, how do you interpret it? (assuming the scope error was rectified)
I think the first part is a pointer to function but its the part from the
-> onwards thats got me stumped.
Can someone point me in the right direction? Thanks
Although the second statement is an error, how do you interpret it? (assuming the scope error was rectified)
Example shows you the difference btw 2 cases:
const int n = 3;
int (*(*f2)(int n))[n];
is basically equivalent to:
const int n = 3;
int (*(*f2)(int n1))[n];
while
const int n = 3;
auto (*f3)(int n)->int (*)[n];
is equivalent to:
const int n = 3;
auto (*f3)(int n1)->int (*)[n1];
and article exlains why. If you mean fixing this code by:
const int n = 3;
auto (*f3)(int n1)->int (*)[n];
then it would declare a pointer to function that accept one parameter of type int and returns pointer to array of 3 ints.
The -> syntax with auto and trailing return type is new in C++11. You can't directly apply the inside-out declaration interpretation rules to the whole thing, only to the separate parts to the left of -> and to the right of ->.
If we get rid of the error
const int n = 3;
auto (*f3)(int m) -> int (*)[n];
then the proper equivalent "classic" version can be written as
const int n = 3;
typedef int (*T)[n];
T (*f3)(int m);
i.e. the int (*)[n] part is the return type.
In other words
T (*f3)(int m);
and
auto (*f3)(int m) -> T;
are the same thing. The typedef helps to emphasize the equivalence.
Related
int r, i, arrayMinimumIndex(auto a)
{
for (int c : a)
c > a[r] ?: r = i, ++i;
return r;
}
I'm trying to run this code but it shows:
[Error] a function-definition is not allowed here before '{' token
[Error] 'arrayMinimumIndex' was not declared in this scope
Can anyone explain why does it fail and fix it ? Thanks in advance
A correct function definition would look like the following:
int arrayMinimumIndex(auto a) //format: return type, methode name, parameters
{
int r = 0, i = 0; //variable definitions in the method body
// search the index..
return r;
}
Alternatively
int r, i, arrayMinimumIndex(auto a);
will work as well. r and i are global in this case. And still you will have to implement the method arrayMinimumIndex later (see above).
Apart from that the call (int c: a) will fail if you are not using C++11 (or higher) because simple arrays do not have iterators implemented. So you should consider passing e.g. an std::vector or walk the array manually like for (int i = 0; i < ...; ++i)
How to convert int to long inside/outside of lambda expression properly? How to check overflow of mathematics inside lambda properly?
int n = 12; // input parameter from std::cin
int a = 23; // input parameter from std::cin
int i = 34; // input parameter from std::cin
auto f = [n, a] (int i) { return a * (n - (i - 1)); };
auto result = f(i);
What's the best way to check for overflow after multiplying of integers inside/outside of lambda?
auto result = f(i);
if ((result > std::numeric_limits<int>::max()) || (result < std::numeric_limits<int>::min())) {
cout << "overflow was detected" << endl;
}
Do I need to add TRT (trailing return type) -> long to lambda for proper conversion from int to long?
auto f = [n, a] (int i) -> long { return a * (n - (i - 1)); };
Do I need to add static_cast to lambda for proper conversion from int to long:
auto f = [n, a] (int i) { return static_cast<long>(a) * (n - (i - 1)); };
Or, may be, I need to combine this?
auto f = [n, a] (int i) -> long { return static_cast<long>(a) * (n - (i - 1)); };
Or, may be, I need to write the type of lambda?
std::function< long( int ) > f = [n, a] (int i) { return a * (n - (i - 1)); };
First part of your question is a duplicate (although C question, C++ doesn't differ, and there are duplicates of including C++). Most important point: You cannot detect signed integer overflow after multiplication, as it already caused undefined behaviour – unless you do calculation in next larger data type; be aware, though, that int and long on many (but not all!) platforms (including Windows on modern PC hardware) have the same size, so switching to long is not a guarantee to avoid overflow! If you want to be safe, use the data types from <cstdint> header (such as int16_t, int32_t, int64_t). If you have some specific reason to insist on int, you'd have to invest some extra work to get guaranteed next larger type. This question is not specific to lambdas, though, but concerns any multiplication (and even addition).
To guarantee a specific return type (again, the question is not specific to lambdas, but to any automatic deduction of type, be it a return type or an auto variable), both aproaches are valuable (explicit trailing return type and a cast), however, as presented, the results do differ!
Just applying the trailing return type is equivalent to having
[n, a] (int i) { return static_cast<long>(a * (n - (i - 1))); };
// ^ ^
Note that the cast is placed around the entire calculation, i. e. the cast is done after the calculation, which still is done in int. If size of int and long do differ, the result can differ from your own casting variant:
[n, a] (int i) { return static_cast<long>(a) * (n - (i - 1)); };
as this enforces already the multiplication being done in long (but not the subtractions! – to enforce even these, too, you'd need to cast i). This cast is entirely sufficient to get the desired return type; an explicit trailing return type (in addition) shows more clearly, though, what the lambda actually returns without having to peek into the implementation. This is especially useful if you have a more complex lambda, and it can help to guarantee a consistent return type if you have multiple exit points.
I am doing some very basic problems to get familiar with Template Metaprogramming. This one in particular is just to add up the values on the down-right diagonal of a square matrix (indexes of [0,0],[1,1], etc.). I have solved this in many ways with different constexpr functions, but I do not understand why one particular way fails. Code and error message below:
constexpr int DRsum(const int* starter, const size_t size, int itr = 0)
{
if(itr==size-1)
{
return *starter;
}
size_t sum = 0;
sum = *starter;
sum += DRsum(starter+size+1, size, itr+1);
return sum;
}
int main()
{
static const size_t size = 3;
static constexpr const int matrix[][size] = {
{1,2,3},
{4,5,6},
{7,8,9}
};
static constexpr int const* baseptr = &matrix[0][0];
constexpr int sum = DRsum(baseptr, size);
}
The error message is as follows:
main.cpp|69| in constexpr expansion of 'DRsum((& matrix[0][0]), 3u, 0)'|
main.cpp|39| in constexpr expansion of 'DRsum((starter + ((((sizetype)size) + 1u) * 4u)),
((size_t)size), (itr + 1))'|
main.cpp|69|error: '* starter' is not a constant expression|
I am not sure why this is doing this, as I am new to Template Metaprogramming. I made a dummy function to test if the pointer dereference was the issue, and that worked out fine. My guess is that it might have to do with me passing in a pointer rather than a pointer to a constexpr pointer, but I'm not sure. Any help would be appreciated, Thanks.
Also, I have already solved this by means of just passing in the entire structure (just straight up a deep copy) but I would rather know how to pass things by shallow copy or pointer into constexpr functions. Thanks.
A 2D array (matrix) cannot be treated as a 1D array, so starter+size+1 results in undefined behavior. Usually undefined behavior is undefined so the program may work as expected, but when an undefined behavior happens within a structure that requires a constant expression, the program becomes ill-formed thus the compiler emits an error.
I don't think there is a simple fix because there is no well-defined way to access the whole 2D array through starter (even with std::launder), unless you change the signature of DRsum. For example, you can write DRsum as follows:
template <size_t size>
constexpr int DRsum(const int (*starter)[size], int itr = 0)
{
if (itr == size - 1)
{
return (*starter)[itr];
}
size_t sum = 0;
sum = (*starter)[itr];
sum += DRsum(starter + 1, itr + 1);
return sum;
}
then call it like constexpr int sum = DRsum(matrix);.
I have C++ code with a type auto:
auto T = reads a JSON
I need to print the content of the T using
cout << T << endl;
It is not working. Can you help me?
With C++11, you can declare a variable or an object without specifying its specific type by using auto.1 For example:
auto i = 42; // i has type int
double f();
auto d = f(); // d has type double
The type of a variable declared with auto is deduced from its initializer. Thus, an initialization is required:
auto i; // ERROR: can’t dedulce the type of i
Additional qualifiers are allowed. For example:
static auto vat = 0.19;
Using auto is especially useful where the type is a pretty long and/or complicated expression. For example:
vector<string> v; ... auto pos = v.begin(); // pos has type vector<string>::iterator
auto l = [] (int x) -> bool { // l has the type of a lambda ..., // taking an int and returning a bool };
In short auto can deduce any type .Your program is not working because it is possible that it is not able to parse JSON or compiler is old (where auto is not supported .Can you specifically let me know the error you got ?
auto in C++ means "set variable type for type of initialization expression", in your case whatever that "reads a JSON" expression returns. You cannot output that type to std::cout because operator<< is not defined for such type, there could be many possible reasons as operator not provided, you suppose to use something else, missing header etc. Solution would depend on actual type.
Ok ! Before telling you how to use auto, I must tell you it's one of the best features of C++11 & has made C++ even more efficient by :-
Reducing amount of code
Enforcing initialization
Increasing genericity (In C++17)
Firstly auto has only 1 job. It will deduce the type of an object by the value passed to it. For ex :-
auto x = 5;
This means that x is an integer whose value is 5. Whenever you are using auto you must initialize the variable (which is a good thing) & you cannot use auto on multiple types in a statement. For ex :-
auto x; // illegal ! x isn't initialized so compiler cannot dduce it's type
auto z=5, y=7; // legal because z & y are both integers
auto a=8, ch= 'c'; // illegal ! an integer & a character in a single statement, hence type deduction ambiguity
The cream of auto is not in intializing int, char, etc data types. It's more handy for classes like iterators. For ex :-
vector<int> v;
vector<int>::iterator i1 = v.begin();
auto i2 = v.begin(); // see how auto reduces the code length
This can be even more obvious in for loops :-
for (vector<int>::iterator i = v.begin(); i!=v.end(); ++i);
Can be reduced to :-
for (auto i = v.begin(), i!=v.end(); ++i);
If you are not happy with the above then this may inspire you to use auto :-
vector< map <int, vector<string> > >::iterator i1 = v.begin(); // where v is the vector of maps of ints & vectors of strings !!!!
auto i2 = v.begin();
The genericity I was talking about is in passing values to functions by auto. Like :-
void add (auto x, auto y)
{
cout << x+y << '\n';
}
This is not possible in current standards & has been proposed for C++17. This is likely to increase the generic ability of the functions without the use of templates. However this syntax is possible for lambda functions :-
auto l = [](auto x, auto y) { return x+y; } // legal from C++14 onwards
However be careful when using braces with lambda because you may think that :-
auto x = {5};
Is an integer but it is actually an intializer_list<int> type object. I can explain a hell lot about auto but I guess for now this is more than enough.
How is auto implemented in C++11? I tried following and it works in C++11
auto a = 1;
// auto = double
auto b = 3.14159;
// auto = vector<wstring>::iterator
vector<wstring> myStrings;
auto c = myStrings.begin();
// auto = vector<vector<char> >::iterator
vector<vector<char> > myCharacterGrid;
auto d = myCharacterGrid.begin();
// auto = (int *)
auto e = new int[5];
// auto = double
auto f = floor(b);
I want to check how this can be achieved using plain C++
It does roughly the same thing as it would use for type deduction in a function template, so for example:
auto x = 1;
does kind of the same sort of thing as:
template <class T>
T function(T x) { return input; }
function(1);
The compiler has to figure out the type of the expression you pass as the parameter, and from it instantiate the function template with the appropriate type. If we start from this, then decltype is basically giving us what would be T in this template, and auto is giving us what would be x in this template.
I suspect the similarity to template type deduction made it much easier for the committee to accept auto and decltype into the language -- they basically just add new ways of accessing the type deduction that's already needed for function templates.
In C++, every expression has value and type. For example, (4+5*2) is an expression which has value equal to 14 and type is int. So when you write this:
auto v = (4+5*2);
the compiler detects the type of the expression on the right side, and replaces auto with the detected type (with some exception, read comments), and it becomes:
int v = (4+5*2); //or simply : int v = 14;
Similarly,
auto b = 3.14159; //becomes double b = 3.14159;
auto e = new int[5]; //becomes int* e = new int[5];
and so on
The auto keyword is simply a way to declare a variable while having it type being based upon the value.
So your
auto b = 3.14159;
Will know that b is a double.
For additional reading on auto take a look at the following references
C++ Little Wonders: The C++11 auto keyword redux
The C++0x auto keyword
It works like before :)
Have you never hit a compiler error telling you:
error: invalid conversion from const char* to int
for such a code fragment: int i = "4";
Well, auto simply leverages the fact that the compiler knows the type of the expression on the right hand side of the = sign and reuses it to type the variable you declare.