This question already has answers here:
C++0x: How can I access variadic tuple members by index at runtime?
(4 answers)
Closed 6 years ago.
I'm trying to do this.
int flag = 0;
if(big.size() <= small.size())
flag = 1; //use float
tuple<long, float> tup (1234.5678, 12341234.1234);
auto foo = get<flag>(tup);
But I get errors:
error: the value of 'flag' is not usable in a constant expression
cout << get<flag>(tup);
-and-
note: 'int flag' is not const
int flag = 0;
Since the value of flag is not known at compile time, it cannot be used a template parameter.
You'll need to use something like:
tuple<long, float> tup (1234.5678, 12341234.1234);
if ( flag )
{
auto foo = get<1>(tup);
}
else
{
auto foo = get<0>(tup);
}
Related
I have a function which needs to parse some arguments and several if clauses inside it need to perform similar actions. In order to reduce typing and help keep the code readable, I thought I'd use a lambda to encapsulate the recurring actions, but I'm having trouble finding sufficient info to determine whether I'm mistakenly invoking undefined behavior or what I need to do to actualize my approach.
Below is a simplified code snippet of what I have currently:
int foo(int argc, char* argv[])
{
Using ss = std::istringstream;
auto sf = [&](ss&& stream) -> ss& {
stream.exceptions(ss::failbit);
return stream;
};
int retVal = 0;
bool valA = false;
bool valB = false;
try
{
for(int i=1; i < argc; i++)
{
std::string arg( argv[i] );
if( !valA )
{
valA = true;
sf( ss(arg) ) >> myInt;
}
else
if( !valB )
{
valB = true;
sf( ss(arg) ) >> std::hex >> myOtherInt;
}
}
}
catch( std::exception& err )
{
retVal = -1;
std::cerr << err.what() << std::endl;
}
return retVal;
}
First, based on what I've read, I don't think that specifying the lambda argument as an rvalue reference (ss&&) is doing quite what I want it to do, however, trying to compile with it declared as a normal reference (ss&) failed with the error cannot bind non-const lvalue reference of type 'ss&'. Changing ss& to ss&& got rid of the error and did not produce any warnings, but I'm not convinced that I'm using that construct correctly.
I've tried reading up on the various definitions for each, but the wording is a bit confusing.
I guess ultimately my questions are:
Can I expect the lifetime of my temporary ss(arg) object to extend through the entire extraction expression?
What is the correct way to define a lambda such that I can use the lambda in the way I demonstrate above, assuming that such a thing is actually possible?
From /snap/dlang/43/usr/include/dlang/dmd/std/process.d:
string[string] toAA() #trusted
{
import std.conv : to;
string[string] aa;
version (Posix)
{
auto environ = getEnvironPtr;
for (int i=0; environ[i] != null; ++i)
{
import std.string : indexOf;
immutable varDef = to!string(environ[i]);
immutable eq = indexOf(varDef, '=');
assert(eq >= 0);
immutable name = varDef[0 .. eq];
immutable value = varDef[eq+1 .. $];
// In POSIX, environment variables may be defined more
// than once. This is a security issue, which we avoid
// by checking whether the key already exists in the array.
// For more info:
// http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html
if (name !in aa) aa[name] = value;
}
}
// ...
}
But getEnvironPtr() is defined as follows:
extern(C) extern __gshared const char** environ;
const(char**) getEnvironPtr() #trusted
{
return environ;
}
The above code seems for me beign not thread safe because of use __gshared and the fact that environ extern variable is modifyable. Is this a bug in D? Or what may I misunderstand?
This is the only way to do it in Posix. The variable is marked const, so you can't modify it, but you can declare another extern(C) variable that can modify the same memory. So don't do that.
D does a lot to make things safe, but the only way to make this truly safe would be to eliminate extern(C). Or to get rid of Posix and rebuild an OS from scratch in D. Those are both drastic measures disproportionate to the size of the problem.
i have declared a map below using stl and inserted some values in it.
#include<bits/stdc++.h>
int main()
{
map<int,int> m;
m[1]=1;
m[2]=1;
m[3]=1;
m[4]=1;
m[5]=1;
m[6]=1;
for(auto it=m.begin();it!=m.end();)
{
cout<<it->first<<" "<<it->second<<endl;
it=it++;
}
return 0;
}
When i executed the above written code it ended up in an infinite loop. Can someone tell me why it does so?
I am incrementing the value of iterator it and then it gets stored in it which should get incremented next time the loop is executed and eventually it should terminate normally.Am i wrong?
The bad line is it = it++;. It is undefined behavior! Because it is not defined, when it is increased, in your case it is increased before the assingment to itsself again, that the value of it before it is increased is assigned to it again and so it keeps at the first position. The correct line would be it = ++it; or only ++it;/it++;, because it changes itsself.
Edit
That is only undefined with the builtin types, but in here that is defined by the source-code of the map in the stl.
If you try doing something similar with an int, you'll get a warning:
int nums[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof nums / sizeof *nums; ) {
cout << nums[i] << '\n';
i = i++;
}
warning: operation on 'i' may be undefined [-Wsequence-point]
However, when you're using a class (std::map::iterator) which has operator overloading, the compiler probably isn't smart enought to detect this.
In other words, what you're doing is a sequence point violation, so the behavior is undefined behavior.
The post-increment operation would behave like this:
iterator operator ++ (int) {
auto copy = *this;
++*this;
return copy;
}
So, what happens to your increment step is that iterator it would get overwritten by the copy of its original value. If the map isn't empty, your loop would remain stuck on the first element.
hello guys i am new to maps in C++ i am having a question regarding copying a particular type map to another map of same kind the details are shown below
I initially declared a map like this
map<string,int> objmap,obj_porcess ;
for(int i = 0; i < 10; i++) {
objmap ["process"+to_string(i)]=i+10//some processing the to_string is just in case but i have strings with names for all 10 values
}
like
objmap["process_today"]=1;
objmap["process_yesterday"]=-1;
objmap["process_tommorow"]=2;
now i want to define some thing like this just my key word should be added with the process and remaining all can be same for all the keys from obj_process
obj_process["today"]=objmap["process_today"] ;
instead of defining all 10 can i have a simple code cause in here i took an example of 10 but i have like 200 set of different strings in the key of map
i already asked a qn for exact opposite one this was my previous qn now when i try its vice versa i got an issue hope i find some help
If you can initialize both at the same time, the solution is straightforward:
const std::vector<std::string> days = {"today", "yesterday", /*...*/};
for(const auto& d : days)
{
objmap["process_" + d] = foo();
obj_process[d] = foo();
}
If you cannot, you should be able to iterate over objmap and get rid of the "process_" prefix with some basic string manipulation:
constexpr auto prefix_length = 8; // length of "process_"
for (const auto& p : objmap)
{
const auto& key = p.first;
const auto& processed_key = key.substr(prefix_length);
obj_process[processed_key] = objmap[key];
}
I was reading C# 4 in a Nutshell and I've come to this piece of code:
IQueryable<Product> SearchProducts (params string[] keywords)
{
IQueryable<Product> query = dataContext.Products;
foreach (string keyword in keywords)
{
string temp = keyword;
query = query.Where (p => p.Description.Contains (temp));
}
return query;
}
Right after the code there's a 'warning' that goes like this:
The temporary variable in the loop is required to avoid the outer variable trap, where the same variable is captured for each iteration of the foreach loop.
I don't get it, I don't understand why the temp variable is necessary. What is the outter variable trap?
From: http://www.albahari.com/nutshell/predicatebuilder.aspx
Can anybody please clarify this?
Because there is only one variable called keyword that is closed over. The temporary variable, however, is different each iteration.
Thus, without the temporary variable, when the lambda is executed later, keyword evaluates to the last value it was assigned in the loop.
Another solution, in some cases, is to force the evaluation (and end up with a List or such).
The problem is that keyword is changing. The => delegate closes on the current value of the variable, not the value it had back in the past when the delegate was created. There's a detailed explanation in Eric Lippert's blog post.
This classic C bug is the same mistake:
#include <stdio.h>
#include <pthread.h>
void * MyThreadFunction(void *x)
{
printf("I am thread %d\n", * (int *) x);
return NULL;
}
int main(void)
{
int i;
pthread_t t[10];
void *ret;
for(i=0; i<10; i++)
pthread_create(&t[i], NULL, MyThreadFunction, (void *) &i);
for(i=0; i<10; i++)
pthread_join(t[i], &ret);
}
The * (int *) x gets the current value of i, not the value when the thread was created.