I am trying to cin a loop index's value in the loop itself using lambda expression:
#include<iostream>
using namespace std;
int main(){
for(int a, ([](int & b){cin>>b;})(a); a < 2; ++a);
return 0;
}
These are the errors when i compile using g++ 4.5 on ubuntu:
forLoopAndCinTest.c++: In function ‘int main()’:
forLoopAndCinTest.c++:5:14: error: expected unqualified-id before ‘[’ token
forLoopAndCinTest.c++:5:14: error: expected ‘)’ before ‘[’ token
forLoopAndCinTest.c++:5:34: error: expected primary-expression before ‘)’ token
forLoopAndCinTest.c++:5:34: error: expected ‘;’ before ‘)’ token
forLoopAndCinTest.c++:5:40: error: name lookup of ‘a’ changed for ISO ‘for’ scoping
forLoopAndCinTest.c++:5:40: note: (if you use ‘-fpermissive’ G++ will accept your code)
forLoopAndCinTest.c++:5:50: error: expected ‘;’ before ‘)’ token
If i use a normal function instead of the lambda, program compiles fine.
Using -fpermissive doesnt help either.
Any ideas?
That's not how the for look works. You are trying to call a lambda where the compiler expects you to declare an int:
for( int a, int2, ...; a < 2; ++a );
Now,
If i use a normal function instead of
the lambda, program compiles fine
Yes, but it's probably not doing what you think it does.
void f(int& b)
{
cin >> b;
}
// ...
for( int a, f(a); a < 2; ++a );
Here, the loop declares two int variables, named a and f. The loop doesn't call f() as you might expect.
Try this instead:
for( int a; cin >> a && a < 2; ++a );
The first part of the for is interpreted as a declaration. We get the very same error when replacing your code by the (almost) equivalent :
int main(){
int a, ([](int & b){cin>>b;})(a); // This produces the same error
for(; a < 2; ++a);
return 0;
}
To answer a comment you made, for (int a, foo() ; ... works, but not like you think it does. It is in fact declaring a function (inside the for scope) that returns an int, and has the name foo. As in :
int a, foo();
Which you should read as :
int a;
int foo();
After this: for( int a, compiler expects some name (of the variable) - unqualified-id.
But in your case it is not so.
Related
I'm new to Sycl/DPC++ language. I wrote a sample vector addition code using Unified shared memory (USM):
#include<CL/sycl.hpp>
#include<iostream>
#include<chrono>
using namespace sycl;
int main()
{
int n=100;
int i;
queue q{ };
range<1>(n);
int *a=malloc_shared<int>(n,q);
int *b=malloc_shared<int>(n,q);
int *c=malloc_shared<int>(n,q);
for(i=0;i<n;i++)
{
a[i]=i;
b[i]=n-i;
}
q.parallel_for(n,[=](auto &i){
c[i]=a[i]+b[i];
}).wait();
for(i=0;i<n;i++){
std::cout<<c[i]<<std::endl;
}
free(a,q);
free(b,q);
free(c,q);
return 0;
}
When I compile it I get the following error:
warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'n' [-Wvexing-parse]
range<1>(n);
^~~
vec_add.cpp:11:1: note: add enclosing parentheses to perform a function-style cast
range<1>(n);
^
( )
vec_add.cpp:11:9: note: remove parentheses to silence this warning
range<1>(n);
^ ~
vec_add.cpp:11:10: error: redefinition of 'n' with a different type: 'range<1>' vs 'int'
range<1>(n);
^
vec_add.cpp:8:5: note: previous definition is here
int n=100;
^
1 warning and 1 error generated.
How to fix this error?
error: redefinition of 'n' with a different type: 'range<1>' vs 'int'
Two variables with the same name within the same scope create confusion to the compiler, so it might be the reason for the error which you are getting. You can try defining the value of n globally say for eg: #define N 100 in this case, set
range<1>(n);
to
range<1> (N);
and use that in your code.
If you want to declare the size locally then assign another variable (r) to the range as
range<1> r (n);
Now you can directly pass the 'r' variable as a parameter to the parallel_for.
I am trying to launch a function threaded using launch::async. However, I noticed that this doesn't work when passing struct elements as parameter:
The code
#include <future>
#include <vector>
#include <thread>
struct example { int ten; };
void threadFunction(int number, std::string hi) {
printf("%s Your number is %d\n", hi.c_str(), number + 1);
}
int main() {
example ex;
ex.ten = 9;
std::string someString = "Hi there!";
std::vector< std::future< void > > threads(5);
for (uint16_t s = 0; s < 5; s += 1) {
threads[s] = async(std::launch::async,
[ex.ten,
someString] {
threadFunction(ex.ten, someString);
});
}
}
gives the following errors:
file.cpp: In function ‘int main()’:
file.cpp:25:39: error: expected ‘,’ before ‘.’ token
[ex.ten,
^
file.cpp:25:39: error: expected identifier before ‘.’ token
file.cpp:25:43: error: expected ‘]’ before ‘,’ token
[ex.ten,
^
file.cpp: In lambda function:
file.cpp:25:43: error: expected ‘{’ before ‘,’ token
file.cpp: In function ‘int main()’:
file.cpp:26:46: error: expected ‘)’ before ‘]’ token
someString] {
^
file.cpp:28:8: error: expected primary-expression before ‘)’ token
});
When replacing ex.ten with some other variable ten it does work.
So my questions are:
1. Why does launch::async not work with struct elements?
2. Is there a way to do it in a more elegant way than to make a variable for each element in the struct and pass those variables instead? (such as int ten = ex.ten; etc)
You can't pass single struct field that way into lambda in C++. The error you get is not connected to std::launch or communicating between threads. What you can do instead is:
C++11 - copy field into local variable and capture that variable:
auto ten = ex.ten;
threads[s] = async(std::launch::async,
[ten,
someString] {
threadFunction(ten, someString);})
C++14 and later - initialize variable in capture list:
threads[s] = async(std::launch::async,
[ten = ex.ten,
someString] {threadFunction(ten, someString);})
What you are trying to do is to capture a field in the struct in lambda. This is not possible, you can only capture the whole struct.
It has nothing to do with std::launch, it's a basic property of lambda closure.
In C++14, you can have captures with initializers, which might be what you want:
auto lam = [ten = ex.ten]...
I am trying to safely input an integer between 1 and 25 but the code I've been told to use does not work properly. That's the code:
*int SafelyInputInteger(int lowerBound, int upperBound)
{
int intNumber;
do {
cout<<"Input a number: "; cin>>intNumber;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
continue;
}
} while((intNumber<lowerBound)||(intNumber>upperBound));
return intNumber;
}
int main()
{
int height;
height=SafelyInputInteger(1,25);
cout<<"Height is: "<<height<<endl;
return 0;
}*
The error I get is the following:
error: 'numeric_limits' was not declared in this scope
error: expected primary-expression before '>' token
error: no matching function for call to 'max()'
The exact error you mentioned occurs when compiling with GCC and not including <limits> header.
<source>: In function 'int SafelyInputInteger(int, int)':
<source>:16:24: error: 'numeric_limits' was not declared in this scope
cin.ignore(numeric_limits<streamsize>::max(),'\n');
^~~~~~~~~~~~~~
<source>:16:49: error: expected primary-expression before '>' token
cin.ignore(numeric_limits<streamsize>::max(),'\n');
^
<source>:16:56: error: no matching function for call to 'max()'
cin.ignore(numeric_limits<streamsize>::max(),'\n');
See live demo here. Compiler version used: GCC 8.2
Including the <limits> header resolves this issue.
I was trying to implement mergesort in cpp. However, the Dev-cpp 5.6.1 reports some "not in this scope" error. It said, "lo", "mid", and "hi" was not declared in this scope. Can you tell me why this happens? Thanks.
#include<iostream>
using namespace std;
void merge(int nums[], int lo, int mid, int hi) {
int n1 = mid - lo + 1;
int n2 = hi - mid + 1;
/*Other implementation code omitted*/
}
int main() {
/*code to Input numbers into nums[]*/
merge(nums, 0, 4, 9);
return 0;
}
When reading error messages that involve syntax errors, it is important to pay the most attention to the very first one. This is because the C++ compiler is not obligated to stop at the first error, and more errors may be produced as a consequence of the first.
In your original code, you have a syntax error in your declaration of the nums parameter to your merge() function:
#include<iostream>
using namespace std;
int nums[10];
void merge(int[] &nums, int lo, int mid, int hi) {
int n1 = mid - lo + 1;
int n2 = hi - mid + 1;
/*Other implementation code omitted*/
}
int main() {
/*code to Input numbers into nums[]*/
merge(nums, 0, 4, 9);
}
You have since edited your program to remove that syntax error, but with this original code, I see the following error messages:
x.cc:3: error: expected ',' or '...' before '&' token
x.cc: In function 'void merge(int*)':
x.cc:4: error: 'mid' was not declared in this scope
x.cc:4: error: 'lo' was not declared in this scope
x.cc:5: error: 'hi' was not declared in this scope
x.cc: In function 'int main()':
x.cc:3: error: too many arguments to function 'void merge(int*)'
x.cc:11: error: at this point in file
You reported the was not declared in this scope errors, but failed to mention the first one, which is pointing out the syntax error for nums. Because of this syntax error, the compiler failed to parse the rest of the function parameters, so it reported those identifiers as having no visible declaration.
Fixing this error removes the others. This is because the parser for the function prototype now picks up the rest of the function arguments, so those are now in scope for the rest of the function.
#define N 10;
int main()
{
int x;
for (int i=0; i<N; i++)
x = i;
return 0;
}
Result of compiling this in g++:
test-define.cpp: In function ‘int main()’:
test-define.cpp:7:22: error: expected primary-expression before ‘;’ token
test-define.cpp:7:22: error: expected ‘)’ before ‘;’ token
test-define.cpp:7:24: error: name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive]
test-define.cpp:7:24: note: (if you use ‘-fpermissive’ G++ will accept your code)
test-define.cpp:7:27: error: expected ‘;’ before ‘)’ token
But it compiles fine when I change line 7 to for (int i=0; i<10; i++).
Why is this and how can I use the #define directive to accomplish what I want?
Remove the semicolon - you will be good - the semicolon is included in the substitution
Sometimes it is useful to get the compiler to run the preprocessor only. With gcc/g++ you can do something like
gcc -E file.c > result.txt
This will show you how the macro expanded (hint start at the end of the file and work up)
I recommend replacing the macro with a constant:
const int N = 10;
It's best to avoid macros when you can. Macros don't have any scope. They are a global text substitution. The compiler never sees them, so if you use a debugger it won't know about them. There are probably other reasons not to use them that I'm forgetting.