简体   繁体   中英

Assign first value that is not zero (c++)

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;

没有简单的方法来扩展它。

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM