Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Is there a way to define a static array inline?

Tags:

c++

templates

I would like to define a simple template function which takes a runtime value and determines if it is a member of some set of possible values.

Usage:

int x;  // <- pretend this came from elsewhere...
if (isoneof(x, {5,3,9,25}) ...

Something like:

template <typename T, size_t size>
bool isoneof(T value, T (&arr)[size])
{
    for (size_t i = 0; i < size; ++i)
        if (value == arr[i])
            return true;
    return false;
}

I assume that this is doomed to failure, as I don't see how one can create a static array inline.

I can use:

int kPossibilities[] = {5,3,9,25};
if (isoneodf(6, kPossibilities)) ...

With a minor change to isoneof:

template <typename T1, typename T2, size_t size>
bool isoneof(T1 value, const T2 (&arr)[size])
{
    for (size_t i = 0; i < size; ++i)
        if (value == arr[i])
            return true;
    return false;
}

Which also makes it a tad more flexible.

Does anyone have an improvement to offer? A better way to define a "set of static values inline"?

like image 263
Mordachai Avatar asked Feb 05 '10 15:02

Mordachai


People also ask

Does inline imply static?

No, inline does not imply static not vice versa.

What does static inline mean?

Static inline functions are simple. Either a function defined with the inline function specifier is inlined at a reference, or a call is made to the actual function. The compiler can choose which to do at each reference. The compiler decides if it is profitable to inline at -xO3 and above.

What is static array in C?

Static arrays are allocated memory at compile time and the memory is allocated on the stack. Whereas, the dynamic arrays are allocated memory at the runtime and the memory is allocated from heap. This is static integer array i.e. fixed memory assigned before runtime int arr[] = { 1, 3, 4 };

How to define an inline variable?

A variable declared inline has the same semantics as a function declared inline: it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there was exactly one variable.


2 Answers

If you like such things, then you will be a very happy user of Boost.Assign.

Boost.Assign actually proves that such semantics are possible, however one look at the source of assign will convince you that you don't want to do that by yourself :)

You will be able to create something like this however:

if (isoneof(x, list_of(2)(3)(5)(7)(11)) { ...

... the downside being you'd have to use boost::array as the parameter instead of a built-in array (thanks, Manuel) -- however, that's a nice moment to actually start using them :>

like image 74
Kornel Kisielewicz Avatar answered Sep 30 '22 02:09

Kornel Kisielewicz


It's possible in the next C++ standard.

Up till then, you can work around it by e.g. overloading operator, for a static object that starts a static array.

Note: this implementation is O(n^2) and may be optimized - it's just to get the idea.

using namespace std;

template< typename T, size_t N > 
struct CHead {
    T values[N];
    template< typename T > CHead<T,N+1> operator,( T t ) { 
      CHead<T,N+1> newhead;
      copy( values, values+N, newhead.values);
      newhead.values[N]=t;
      return newhead;
    }
    bool contains( T t ) const { 
       return find( values, values+N, t ) != values+N; 
    }
};

struct CHeadProto {
  template< typename T > 
  CHead<T,1> operator,( T t ) { 
     CHead<T,1> h = {t}; 
     return h; 
  }
} head;



int main()
{
  assert( (head, 1,2,3,4).contains(1) );
  return 0;
}
like image 45
xtofl Avatar answered Sep 30 '22 00:09

xtofl