I have a simple couple lines of code
std::regex_iterator<std::string::const_iterator>
regit (attributesStart, _curIter, _attributeRegex),
regend(std::regex_iterator<std::string::const_iterator>);
while (regit != regend)
{
// [...]
}
The compiler complains about the while line, saying
Invalid operands to binary expression ('std::regex_iterator' and 'std::regex_iterator (*)(std::regex_iterator)')
Any idea why this is?
int main()
{
int i = 0, f(int);
f(i);
}
int f(int) {return 0;}
Is valid code. There is a block-scope function declaration of f inside main, in the same init-declarator-list as i, which is a usual int.
The same happens in your case, just in a more complicated manner. Here the function declared is regend and has a parameter of type std::regex_iterator<..> - you could have also deduced this by inspecting the error message. The problem wouldn't be solved by using std::regex_iterator<std::string::const_iterator>(); Then the parameter would be a pointer-to-function instead, but regend not a variable. Use uniform initialization (i.e. { and }) or double braces to avoid this.
Related
I have a function fun() I wish to overload in the same scope. As per the rules of overloading, different order of arguments should allow for the overloading of the function as mentioned here.
The Code:
#include "iostream"
using namespace std;
void fun(int i, float j)
{
cout << "int,float";
}
void fun(float i, int j)
{
cout << "float,int";
}
int main()
{
fun(20,20);
}
Error:
error: call of overloaded ‘fun(int, int)’ is ambiguous
15 | fun(20,20);
Question:
Had there been only one function with argument fun(int, float), that would have been called as the best match, so why does it throw error in this case.
You give two integers, so the compiler have to convert one into a float, but which function shall be taken?
int main()
{
fun(20.0,20);
fun( 20, 20.0);
}
these calls makes the compiler happy, since you tell which function shall be taken.
The reason why you are facing this error is due to the data type of the arguments you have provided
In this case
fun(20,20);
which are both int, int.
A correct function call in this scenario would be,
fun(20,20.0);
or
fun(20.0,20);
(edit)
as mentioned by Ivan Vnucec
it would be better to explicitly call the function with arguments that are float instead of double
so call it in this way:
fun(20,20.0f);
or
fun(20.0f,20);
I got this declaration from https://en.cppreference.com/w/cpp/language/scope, but don't know how to parse this declaration even there is a comment below.
my questions is
how to parse the declaration statement (I see it as a function pointer to a function protocol like "int[3] foo(int n)" or "int foo(int n)[3] --- they are illegal in C++ )? Then, how can I construct a concrete function which can be assigned to this function pointer? Thanks.
const int n = 3;
int (*(*f2)(int n))[n]; // OK: the scope of the function parameter 'n'
// ends at the end of its function declarator
// in the array declarator, global n is in scope
// (this declares a pointer to function returning a pointer to an array of 3 int
It's a pointer to a function taking an int and returning a pointer to an int array of size three.
All the comment is saying is that there are two n identifiers in play here. The [n] (in array declarator) is using the const int 3, not the parameter to the function (which is in the function declarator).
Starting in the middle, with each segment being included in the subsequent bullet point as ...:
f2 is a pointer, (*f2).
It's a pointer to a function taking an integer, ...(int).
It returns a pointer to an int array of size three, int (*...)[3].
You can form a concrete function for it as per the following complete program, which output the first element, 42:
#include <iostream>
const int n = 3;
int (*(*f2)(int n))[n];
int (*g2(int))[n] {
static int x[::n] = { 42 }; // Use outer n, not the parameter.
return &x; // since C++ has no VLAs. This
// means parameter is not actually
// needed in this test case, though
// it may be in more complicated
// tests.
}
int main() {
f2 = &g2; // Assign concrete function to pointer.
auto y = f2(3); // Call via pointer, get array.
std::cout << *(y[0]) << '\n'; // Deref first element to get 42.
}
Having said that, I would be rather curious if one of my colleagues submitting something like that for a code review, at least without a large comment explaining it. Although seasoned developers may be able to work it out, those less experienced may have trouble.
And, in fact, even seasoned developers shouldn't have to work it out, especially given it took me a few minutes.
C++ has a very expressive type system which can easily build something like this up in parts, so you don't have to experience migraines trying to work it out. For something like this, I'd be using std::vector (or std::array) unless there was a compelling case for the added complexity caused by more basic types.
You can create a type for pointer to an array of 3 int
typedef int (*array_with_size_n)[n];
and then use it as return type
const int n = 3;
int (*(*f2)(int n))[n];
int arr[n];
array_with_size_n func(int n)
{
return &arr;
}
int main()
{
f2 = &func;
return 0;
}
When using function with same name, parameter list must differ(either in type of parameter or number of parameters used). I was just practicing with this concept. I wrote the following code.
#include <iostream>
int myFunction(int n)
{
return 2*n;
}
float myFunction(float n)
{
return 3*n;
}
int main()
{
int x=myFunction(3);
std::cout << x;
return 0;
}
I thought I will get error because compiler will get confused which myFunction to use because I directly pass the value 3 without storing it in a particular type of variable . But I got output 6. So I tried the following code.
#include <iostream>
int myFunction(int n)
{
return 2*n;
}
float myFunction(float n)
{
return 3*n;
}
int main()
{
float x=myFunction(3.3);
std::cout << x;
return 0;
}
As previous one worked fine, I thought this will work fine too, as 3.3 is not integer so it's clear which one to call, but this time I got compiler error saying it's ambiguous.
So my doubt is why first code worked but not second one.
The process of selecting the overload during a call is called overload resolution. Given the types of the arguments, the compiler selects the best viable function from the list of candidates - the one that can be invoked with the least amount of promotions and implicit conversions.
In the first case the first one myFunction(int) requires 0 conversions for an int argument (3), and the second one requires one conversion (int -> float), so the first one is selected as the best candidate.
In the second case a double argument (3.3) requires a conversion to either int or float, so there is no clear winner and thus the call is ambiguous.
The fix could be to use a float argument (3.3f) or change myFunction(float) to myFunction(double).
Literals have types too. As integer literal 3 is of type int, then the 1st overload is selected.
As floating point literal 3.3 is of type double (but not float; with the suffix f like 3.3f the type is determined as float), the calling is ambiguous because it could convert to both int and float implicitly.
try this:
int x=myFunction(int(3));
float x=myFunction(float(3.3));
I have very simple program here, I get errors like :
conflicting type of 'f'
previous declaration of 'f' was here
error : initializer element is not computable at load time
in function queue_ready:
invalid type argument of unary '*' (have'int')
in function dequeue_ready :
invalid type argument of unary '*' (have'int')
Where are my mistakes?
#include<stdio.h>
int Queue_ready[1000];
int *r ;
int *f ;
r=&Queue_ready[0];
f=&Queue_ready[0];
void queue_ready (int process)
{
*r=process;
r = r+1;
}
void dequeue_ready (void)
{
*f = 10000;
f=f+1;
}
int main()
{
queue_ready(1);
queue_ready(2);
printf("%d %d" , Queue_ready[0] ,Queue_ready[1]);
dequeue_ready();
dequeue_ready();
return 0;
}
The problem is here:
int *r;
int *f;
r=&Queue_ready[0];
f=&Queue_ready[0];
These lines lie outside of a function. The first two are OK, since they declare variables, but the next two are not since they are statements, and statements are not allowed outside of a function.
The reason you're getting a "conflicting type" error is because the statement (that the compiler isn't expecting) is being read as a declaration. Since this "declaration" doesn't specify a type, it has an implied type of int which conflicts with the prior definition of type int *.
Because what you actually want to do is initialize these variables (as opposed to assign), you do so at the time they are declared:
int *r = &Queue_ready[0];
int *f = &Queue_ready[0];
Ok, this might be a stupid question, but I completely don't understand chapter 12.1.6.2 - conditional evaluation under constexpr functions of the c++ programming language. This is the whole very short text.
A branch of a conditional expression that is not taken in a constexpr
function is not evaluated. This implies that a branch not taken can
require run-time evaluation. For example:
constexpr int check(int i)
{
return (low<=i && i<high) ? i : throw out_of_range();
}
constexpr int low = 0;
constexpr int high = 99;
// ...
constexpr int val = check(f(x,y,z));
You might imagine low and high to be configuration parameters that are
known at compile time, but not at design time, and that f(x,y,z)
computes some implementation-dependent value.
Source for context
I tried running the code above to try to more understand the explanation but I'm getting an error. Can someone provide a clearer explanation?
Edit: I created a program to test this:
#include<iostream>
#include<stdexcept>
using namespace std;
constexpr int low = 0;
constexpr int high = 99;
constexpr int check(int i) {
return (low<=i && i<high) ? i : throw out_of_range();
}
constexpr int f(int x, int y, int z) {
return x*y*z;
}
int main() {
constexpr int val = check(f(2,2,2));
cout << val << '\n';
}
It won't run:
no matching function for call to 'std::out_of_range::out_of_range()' //I'm really surprised at this
return (low<=i && i<high) ? i : throw out_of_range();
error: body of constexpr function 'constexpr int check(int)' not a return-statement
}
error: 'constexpr int check(int)' called in a constant expression
constexpr int val = check(f(2,2,2));
It means that a conditional branch in a constexpr function is allowed to use non-constant expressions (i.e. ones requiring run-time evaluation, such as throwing exceptions) as long as that branch is never taken when the function is called in a constant expression context.
So it's OK to call check to initialized the constexpr variable val, as long as the arguments to the function are constant expressions, and the condition (low<=i && i<high) is true.
If the arguments are not constants, the function call is not a constant expression and so can't initialize a constexpr variable.
If the condition is false the function needs to take the false branch, which needs to throw an exception, which requires run-time evaluation, so the function is not a constant expression, and so cannot initialize a constexpr variable.
When the argument is a constant expression, the compiler knows at compile-time whether the branch will be taken, so as long as the condition is true it can completely ignore the false branch, and doesn't complain that throwing exceptions is impossible at compile-time.
When the function is called at run-time, it can have any arguments, and the false branch can be taken and the throw will be evaluated as for a normal (non-constexpr) function.