In JavaScript you can write this:
var foo = value1 || value2.
The result is a new value that is value1 if value1 is not zero and value2 if value1 is zero.
In C++ this expression is evaluated to true or false instead.
Is there a way to imitate this syntax somehow in c++? (for unlimited number of values).
auto foo = value1 ? value1 : value2;
There's no easy way to extend it.
You could use write a generic function that would accept any number of arguments:
#include <initializer_list>
#include <iostream>
int find_first(std::initializer_list<int> args) {
for(int arg : args) {
if (arg) {
return arg;
}
}
return -1;
}
int main(int argc, char** argv) {
std::cout << find_first({0, 0, 1, 2}) << std::endl;
std::cout << find_first({3}) << std::endl;
std::cout << find_first({-1, -2, 0}) << std::endl;
return 0;
}
This prints:
1
3
-1
You could use the ternary operator
int i = (value1 != 0 ? value1 : value2)
This evaluates to
int i;
if (value1 != 0)
i = value1;
else
i = value2;
And the syntax is
(condition ? trueOutput : falseOutput)
Ok so best I could come up with so far is an improvement of the jterrace solution.. :) So far it works with a type Foo that can be assigned from int. This allows the solution to work with a list that consists of objects of multiple types that can all be compared to foo.
Is there anything I can improve further to make this the most generic solution possible?
#include <initializer_list>
#include <iostream>
#include <stdio.h>
class Foo {
public:
Foo(int v){val = v;}
bool operator==(int v) const {return val == v;}
bool operator!=(int v) const {return val != v;}
operator int() const {return val;}
int val;
};
template<class Type>
Type find_first(std::initializer_list<Type> args) {
auto it = args.begin();
for(int c = 0; c < args.size(); c++) {
if (*it != 0) {
return *it;
}
if(c == args.size() - 1) return *it;
it++;
}
// only get here if size == 0
return Type(0);
}
int main(int argc, char** argv) {
Foo *foo = new Foo(0);
Foo bar = 0;
std::cout << find_first<Foo>({*foo, bar, 1}).val << std::endl;
std::cout << find_first<int>({*foo, bar, (int)3.0f}) << std::endl;
return 0;
}
Related
So I had this scenario where I want to call either function of a class, where the function in question has the same prototype but it's also overloaded. Since I know of pointer to members my immediate reaction was something like this:
struct test
{
int overloaded(char) {}
int overloaded(int) {}
int overloadedone(char) {}
int overloadedone(int) {}
} test;
int main()
{
(test.*(true ? (&test::overloaded) : (&test::overloadedone)))(1);
}
However it turned out the compiler (MSVC - 2019 Preview latest version with std C++ preview) can't deduce the type and I have to write:
(test.*(true ? static_cast<int (test::*)(int)>(&test::overloaded) : static_cast<int (test::*)(int)>(&test::overloadedone)))(1);
instead which made me return to the good old:
true ? test.overloaded(1) : test.overloadedone(1);
But I wonder if this is the defined behavior of requiring those cast. Even:
(test.*static_cast<int (test::*)(int)>(true ? (&test::overloaded) : (&test::overloadedone)))(1);
Doesn't work.
You have to write said cast on each of the two possibilities for the ternary as in the second example.
It isn't particularly elegant, but this approach can deduce an overload if you curry the member function pointer's arguments before passing the member function pointers themselves:
#include <iostream>
template <class... Args>
auto invoke_conditional_mem_fn(Args... args)
{
return [=] <class R, class X> (X x, bool b, R(X::*t)(Args...), R(X::*f)(Args...)) -> R
{
return (x.*(b ? t : f))(args...);
};
}
struct test
{
int overloaded(char) { std::cout << "overloaded(char) "; return 1; }
int overloaded(int) { std::cout << "overloaded(int) "; return 2; }
int overloadedone(char) { std::cout << "overloadedone(char) "; return 3; }
int overloadedone(int) { std::cout << "overloadedone(int) "; return 4; }
} test;
int main()
{
std::cout
<< invoke_conditional_mem_fn('1')(test, true, &test::overloaded, &test::overloadedone)
<< std::endl
<< invoke_conditional_mem_fn(1)(test, false, &test::overloaded, &test::overloadedone)
<< std::endl;
}
Thanks to #dyp and their example, we know that we can infer the return type and base of the member function pointers if we select which arguments to pass.
Alternatively, you could do something a little simpler like this, if it meets your needs. Just declare a lambda to work around the limitations of your ternary expression with an if and else statement since each branch of a ternary operator is required to be of the same type.
#include <iostream>
struct test
{
int overloaded(char) { std::cout << "overloaded(char) "; return 1; }
int overloaded(int) { std::cout << "overloaded(int) "; return 2; }
int overloadedone(char) { std::cout << "overloadedone(char) "; return 3; }
int overloadedone(int) { std::cout << "overloadedone(int) "; return 4; }
} test;
auto conditional = [] (struct test& test, bool cond, auto... args)
{
if (cond) return test.overloaded(args...);
else return test.overloadedone(args...);
};
int main()
{
std::cout << conditional(test, true, '1') << std::endl;
std::cout << conditional(test, false, 1) << std::endl;
}
Is there a way to check if certain variable is initialized before some point in a program?
For example, how to check if certain variable is initialized somewhere before the IfStmt node?
Methods from VarDecl class (hasInit() and getInit()) are not enough because of the following situation:
int x = 0; // hasInit() return true
int y;
...
y = 0; // initialized here, but hasInit() returns false
...
if (...) {}
If you maintain a product written by C++ code and hope to remove ugly indeterminate variables, a reasonable way to do it is defining an initializing function or lambda f, and then declare a local variable as const auto x = f(...); from the get-go.
OTOH, if you delay the value asignment on purpose, there are several methods to detect the value is assigned or not.
I just came up with following methods.
std::optional
In C++17 and over,
std::optional<T> enables us to detect whether values are assigned or not.
std::optional::has_value and std::optional::value correspond to your hasInit and getInit respectively as follows:
DEMO
#include <iostream>
#include <optional>
template<typename T>
void checkInitialization(const std::optional<T>& a)
{
if(a.has_value()){
std::cout << "Value is assigned by " << a.value() << "." << std::endl;
}
else{
std::cout << "Value is still not assigned." << std::endl;
}
}
int main(void)
{
std::optional<int> x;
checkInitialization(x); // Value is still not assigned
x = 1;
checkInitialization(x); // Value is assigned
return 0;
}
The output is as follows:
Value is still not assigned.
Value is assigned by 1.
std::unique_ptr
We can also check it using std::unique_ptr<T> which is introduced from C++11.
First we define a variable as std::unique_ptr<T> x; where (x == nullptr) is still true.
Later on, we assign a value by x = std::unique_ptr<int>(new int(1)) and then (x == nullptr) becomes false.
(In C++14 x = std::make_unique<int>(1) works and is simple.)
Thus we can again get the previous output with the following code:
DEMO
#include <iostream>
#include <memory>
template<typename T>
bool hasInit(const std::unique_ptr<T>& a)
{
return (a != nullptr);
}
template<typename T>
const T& getInit(const std::unique_ptr<T>& a)
{
return *a;
}
template<typename T>
void checkInitialization(const std::unique_ptr<T>& a)
{
if(hasInit(a)){
std::cout << "Value is assigned by " << getInit(a) << "." << std::endl;
}
else{
std::cout << "Value is still not assigned." << std::endl;
}
}
int main(void)
{
std::unique_ptr<int> x;
checkInitialization(x); // Uninitialized
x = std::unique_ptr<int>(new int(1));
//x = std::make_unique<int>(1); // C++14
checkInitialization(x); // Initialized
return 0;
}
std::pair
We can also apply std::pair<bool, T> where std::pair::first and std::pair::second correspond to your hasInit and getInit respectively.
We again get the previous output:
DEMO
#include <iostream>
#include <utility>
template<typename T>
void checkInitialization(const std::pair<bool, T>& a)
{
if(a.first){
std::cout << "Value is assigned by " << a.second << "." << std::endl;
}
else{
std::cout << "Value is still not assigned." << std::endl;
}
}
int main(void)
{
std::pair<bool, int> x{false, 0};
checkInitialization(x); // Uninitialized
x = {true, 1};
checkInitialization(x); // Initialized
return 0;
}
Firstly as mentioned in the comments:
int y = 0; // initialization
int y; y = 0; // assignment
Let's assume you want to detect assignment. One simple way could be wrap the integer you want to track in a struct and write a custom operator = (int). For example:
struct Foo
{
Foo() {std::cout << "default init" << std::endl;}
Foo& operator = (int elem)
{
cout<<"Int-Assignment operator called "<<endl;
x = elem;
is_assigned = true;
return *this;
}
int x = 0; // default initialized to 0
bool is_assigned = false; // default initialized to false
};
Now let's see what happens:
int main()
{
Foo t1;
// t1.is_assigned is false
t1 = 0;
// t1.is_assigned is true
return 0;
}
You could use something like this or a variant if needed. Here's the code running online corresponding to the above.
Is this what you wanted?
I have some global variables that will be assigned a value once the configuration file is read.
bool bar1;
int bar2;
string bar3;
I read the configuration file which looks like below:
foo1 = 12
foo2 = 0
foo3 = 1
...
void func()
{
//read file into a std::map mp
for(auto i:mp)
{
if(i.first=="foo1")
bar1 = i.second;
else if(i.first=="foo2")
bar2 = i.second;
else if(i.first=="foo3")
bar3 = i.second;
.....
}
}
I have a lot of such variables to initialize from a file. Is there a better way to do this because this will bloat my function.
PS:I am still stuck with C++03.
In my comment, I elaborated a bit on the idea of Jabberwocky to use a std::map.
Actually, we do similar things in our S/W for configuration and similar things. The only difference – we don't use a std::map for this but a pre-defined array. (I didn't like the idea that something has to be done at run-time which actually never changes after compiling.) To demonstrate the concept I made a little MCVE:
#include <iostream>
#include <cassert>
#include <cstring>
#include <algorithm>
#include <map>
int main()
{
// variables
int bar1 = 0, bar2 = 0, bar3 = 0;
// symbol table
const struct Entry { const char *key; int *pVar; } table[] = {
{ "foo1", &bar1 },
{ "foo2", &bar2 },
{ "foo3", &bar3 }
};
const size_t nTable = sizeof table / sizeof *table;
// check that table has correct order
assert([&]()
{
for (size_t i = 1; i < nTable; ++i) {
if (strcmp(table[i - 1].key, table[i].key) >= 0) return false;
}
return true;
}());
// use table in tests
std::pair<const char*, int> mp[] = {
{ "foo1", 123 },
{ "foo2", 234 },
{ "foo3", 345 },
{ "wrong", 666 }
};
// evaluate mp of OP
for (auto i : mp) {
const Entry e = { i.first, 0 };
const auto iter
= std::lower_bound(std::begin(table), std::end(table), e,
[](const Entry &e1, const Entry &e2) { return strcmp(e1.key, e2.key) < 0; });
if (iter != std::end(table) && strcmp(iter->key, i.first) == 0) *iter->pVar = i.second;
else std::cerr << "Unknown var '" << i.first << "'!\n";
}
// print result
std::cout
<< "bar1: " << bar1 << '\n'
<< "bar2: " << bar2 << '\n'
<< "bar3: " << bar3 << '\n';
// done
return 0;
}
Output:
Unknown var 'wrong'!
bar1: 123
bar2: 234
bar3: 345
Live Demo on coliru
The essential part is the struct Entry which groups the name of an option with the address of the corresponding variable. This could be used to store pairs of names and variable addresses in a std::map.
I used instead a pre-sorted array. (Sorting the keys manually in programming is not that difficult – in case of accidents the assert() will alert.)
In our productive S/W, we didn't use addresses of variables but method pointers to setter functions as the destination variables have varying types and the values (provide as string) are subject of a resp. parsing. However, these method pointers are compile-time solvable → the whole table can be static. Hence, the effort for building up the table for each function call is prevented. In this demo, the table stores addresses to local variables. This let me feel that a static table could be a bad idea (and I even didn't try it).
Upon request, here another demonstration using method pointers to setter methods:
#include <iostream>
#include <cassert>
#include <cstring>
#include <string>
#include <algorithm>
class Object {
private:
// some member variables:
int var1, var2;
std::string var3;
double var4;
public:
Object(): var1(), var2(), var4() { }
friend std::ostream& operator<<(std::ostream &out, const Object &obj);
// the setter methods
void setVar1(const char *value) { var1 = atoi(value); }
void setVar2(const char *value) { var2 = atoi(value); }
void setVar3(const char *value) { var3 = value; }
void setVar4(const char *value) { var4 = strtod(value, nullptr); }
// the config method to set value by text
void config(const char *key, const char *value)
{
// symbol table
static const struct Entry {
const char *key; // the symbol
void (Object::*set)(const char*); // the corresponding setter method
} table[] = {
{ "var1", &Object::setVar1 },
{ "var2", &Object::setVar2 },
{ "var3", &Object::setVar3 },
{ "var4", &Object::setVar4 }
};
enum { nTable = sizeof table / sizeof *table };
// check that table has correct order (paranoid - debug only code)
assert([&]()
{
for (size_t i = 1; i < nTable; ++i) {
if (strcmp(table[i - 1].key, table[i].key) >= 0) return false;
}
return true;
}());
// find setter by key
const Entry e = { key, nullptr };
const auto iter
= std::lower_bound(std::begin(table), std::end(table), e,
[](const Entry &e1, const Entry &e2) { return strcmp(e1.key, e2.key) < 0; });
if (iter != std::end(table) && strcmp(iter->key, key) == 0) {
(this->*iter->set)(value);
} else std::cerr << "Unknown var '" << key << "'!\n";
}
};
std::ostream& operator<<(std::ostream &out, const Object &obj)
{
return out
<< "var1: " << obj.var1 << ", var2: " << obj.var2
<< ", var3: '" << obj.var3 << "', var4: " << obj.var4;
}
int main()
{
Object obj;
// print obj before config:
std::cout << "obj: " << obj << '\n';
// configure obj
std::pair<const char*, const char*> config[] = {
{ "var1", "123" },
{ "var2", "456" },
{ "var3", "text" },
{ "var4", "1.23" },
{ "evil", "666" }
};
for (const auto& entry : config) {
obj.config(entry.first, entry.second);
}
// print obj after config:
std::cout << "obj: " << obj << '\n';
// done
return 0;
}
Output:
obj: var1: 0, var2: 0, var3: '', var4: 0
Unknown var 'evil'!
obj: var1: 123, var2: 456, var3: 'text', var4: 1.23
The contents of table (in Object::config()) is static const and will be built at compile-time (and hopefully "burnt" into the binary). Hence, the multiple calls of Object::config() have the only effort of binary search of the matching key and calling the setter in case of success.
A essential pre-condition is that all setter methods have the same signature. Otherwise, storing them in an array wouldn't be possible as they all have to be compatible to the method pointer element in the array.
Live Demo on coliru
#include <iostream>
typedef std::function<bool(int)> set;
using namespace std;
set singletonSet(int a) {
return [&] (int x) { return (a == x); };
}
bool contains(set s, int test) {
return s(test);
}
int main() {
auto first = singletonSet(5);
auto r1 = contains(first, 10);
auto r2 = contains(first, 5);
cout << r1 << " " << r2 << endl;
return 0;
}
I expect this to print 0 1 but result is 1 1
Beginner c++ labmda programmer here so sorry in advance if this is a basic error.
Don't capture a by reference, capture it by value. As-is, you're storing a dangling reference inside the lambda, and using it later leads to UB.
set singletonSet(int a) {
return [=] (int x) { return (a == x); };
// ^
}
I have:
const char kLetters[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
I can call kLetters[n] to obtain the nth letter of the Keyboard alphabet in O(1) time. However I will have to iterate through kLetter (taking O(n) or at least O(log n) ) time for the reverse lookup.
I would like to create a reverse lookup table as a compile-time static lookup table using templates and was wondering if there is a ways of doing this.
EDIT - as mentioned in the comments, a reverse lookup would mean I supply 'E' and get back 2. Also my alphabet example was not the best example, I would like to make no assumptions about the order. For that reason I have change the alphabet to keyboard order.
How about something like this? It lets you specify the range rather than a complete string.
#include <iostream>
template <int Start, int End, int N>
struct lookup {
static_assert(Start != End, "Can't have 0 length lookup table");
enum { value = lookup<Start+(Start < End ? 1:-1),End,N-1>::value };
};
template <int Start, int End>
struct lookup<Start,End,0> {
enum { value = Start };
};
template <int Start, int End, int V, int P=0>
struct reverse_lookup {
static_assert(Start != End, "V isn't in the range Start, End");
static_assert(Start != End || !P, "Can't have 0 length range");
enum { value = reverse_lookup<Start+(Start < End ? 1:-1),End,V,P+1>::value };
};
template <int Start, int End, int P>
struct reverse_lookup<Start,End,Start,P> {
enum { value = P };
};
int main() {
std::cout << char(lookup<'A', 'Z', 3>::value) << std::endl;
std::cout << char(lookup<'Z', 'A', 3>::value) << std::endl;
std::cout << int(reverse_lookup<'A','Z','F'>::value) << std::endl;
}
Alright, after knowing what reverse lookup is, I think you can do this:
const char kLetters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int get_index(char letter)
{
return letter - 'A';
}
After all, the letter A is at index 0, B at 1, C at 2... and so on. That gives enough hint.
My O(1) solution.
So far other solutions work for non-arbitrary sequence of letters, and #awoodland solution assumes that the letter whose index is to be obtainted is known at compile time which makes it less useful.
But this solution has attempted to solve both limitations; that is, it should work:
With arbitrary sequence of letters, such as
const char Letters[] = "ZBADCEWFVGHIUXJTKSLYQMROPN";
And the letters may be unknown at compile time. The function that gets the index has this signature:
int Index(char letter);
Here is the complete code which uses a technique described by # David Rodríguez in his blog:
#include <iostream>
const char Letters[] = "ZBADCEWFVGHIUXJTKSLYQMROPN";
template<char L> int Index();
template<> int Index<'Z'>() { return 0; }
template<> int Index<'B'>() { return 1; }
template<> int Index<'A'>() { return 2; }
template<> int Index<'D'>() { return 3; }
template<> int Index<'C'>() { return 4; }
template<> int Index<'E'>() { return 5; }
template<> int Index<'W'>() { return 6; }
template<> int Index<'F'>() { return 7; }
template<> int Index<'V'>() { return 8; }
template<> int Index<'G'>() { return 9; }
template<> int Index<'H'>() { return 10; }
template<> int Index<'I'>() { return 11; }
template<> int Index<'U'>() { return 12; }
template<> int Index<'X'>() { return 13; }
template<> int Index<'J'>() { return 14; }
template<> int Index<'T'>() { return 15; }
template<> int Index<'K'>() { return 16; }
template<> int Index<'S'>() { return 17; }
template<> int Index<'L'>() { return 18; }
template<> int Index<'Y'>() { return 19; }
template<> int Index<'Q'>() { return 20; }
template<> int Index<'M'>() { return 21; }
template<> int Index<'R'>() { return 22; }
template<> int Index<'O'>() { return 23; }
template<> int Index<'P'>() { return 24; }
template<> int Index<'N'>() { return 25; }
typedef int (*fptr)();
const int limit = 26;
fptr indexLookup[ limit ];
template <char L>
struct init_indexLookup {
static void init( fptr *indexLookup ) {
indexLookup[ L - 'A' ] = &Index<L>;
init_indexLookup<L-1>::init( indexLookup );
}
};
template <>
struct init_indexLookup<'A'> {
static void init( fptr *indexLookup ) {
indexLookup[ 0 ] = &Index<'A'>;
}
};
const int ignore = (init_indexLookup<'Z'>::init(indexLookup),0);
int Index(char letter)
{
return indexLookup[letter-'A']();
}
And here is the test code:
int main()
{
std::cout << Index('A') << std::endl;
std::cout << Index('Z') << std::endl;
std::cout << Index('B') << std::endl;
std::cout << Index('K') << std::endl;
}
Output:
2
0
1
16
Online demo : http://ideone.com/uzE2t
Well, that actually is two function calls: one to Index(), other to from one in the indexLookup. You can easily avoid first function call by writing (ideone):
int main()
{
std::cout << indexLookup['A'-'A']() << std::endl;
std::cout << indexLookup['Z'-'A']() << std::endl;
std::cout << indexLookup['B'-'A']() << std::endl;
std::cout << indexLookup['K'-'A']() << std::endl;
}
That looks cumbersome, but hey, we can make Index() inline:
inline int Index(char letter)
{
return indexLookup[letter-'A']();
}
That looks fine, and most likely now compiler will make it equivalent to one function call!
Simple yet O(1) solution
Wait. I just realized that the whole solution reduces to a lookup table which is initialized as:
const int indexLookup[] = {2,1,4,3,5,7,9,10,11,14,16,18,21,
25,23,24,20,22,17,15,12,8,6,13,19,0};
inline int Index(char letter)
{
return indexLookup[letter-'A'];
}
which looks unbelievably simple!
If you can use Boost and only need compile-time lookups:
using namespace boost::mpl;
typedef vector_c<char, 'A', 'B', 'C', 'D'> Chars;
// lookup by index:
std::cout << at_c<Chars, 1>::type::value << std::endl; // B
// lookup by value:
typedef find<Chars, integral_c<char, 'C'> >::type Iter;
std::cout << Iter::pos::value << std::endl; // 2
This assumes that 'Z' > 'A', but does not assume letters are contiguous. (Though it takes less memory if they are) I was tempted to put in if (numrLetters>26) conditionals so a smart compiler could use addition rather than the tables for ASCII, but then decided I didn't want to slow the code in the case of less-smart compilers.
const char kLetters[] = "ABCDEFGHJJKLMNOPQRSTUVWXYZ";
const int numLetters = sizeof(kLetters);
const char rkLetters['Z'-'A'] = {};
const int numrLetters = sizeof(rkLetters);
struct LetterInit {
LetterInit() {
for(int i=0; i<numLetters; ++i)
rkLetters[kLetters[i]-'A'] = i;
}
}LetterInitInst;
char findChar(int index) {
assert(index>=0 && index<numLetters);
return kLetters[index];
}
int findIndex(char letter) {
assert(letter>='A' && letter<='Z');
return rkLetters[letter-'A'];
}
As there are several solutions given that don't generate a table but still allow compile time lookup, here is another one
constexpr char kLetters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
constexpr int get(char const x, int const i = 0) {
return kLetters[i] == x ? i : get(x, i + 1);
}
Use at compile time
int x[get('F')];
static_assert(sizeof(x) == sizeof(int[5]), "");
Specifying a character that doesn't exist will result in an error. If you use the function at runtime, you will get undefined behavior if you specify a character that doesn't exist. Proper checking can be added for those cases.
It yields the index of the first character found. No error is given if a character appears twice in the haystack.
If you can use c++0x (tested with gcc 4.5), this works:
#include<initializer_list>
#include<iostream>
#include<map>
constexpr int getLetterNumber(char a){ return std::map<char,int>({{'a',2},{'b',1},{'c',4}})[a]; }
int main(){
const char ch='b';
std::cout<<ch<<": "<<getLetterNumber(ch)<<std::endl;
}
constexpr enforces evaluation at compile-time.
EDIT: that solution is not correct, as pointed out. constexpr does not enfoce compile-time evaluation. This does does the lookup really at compile-time (similar to solutions posted meanwhile).
#include<iostream>
template<char C> int ch2Num();
#define CHR(c,i) template<> int ch2Num<c>(){ return i; }
CHR('a',2); CHR('b',1); /* ... */
#undef CHR
int main(void){
const char ch='b';
std::cout<<ch<<": "<<ch2Num<ch>()<<std::endl;
};