9

それが可能かどうかはわかりませんが、次のようなことをしたいです

int someval = 1;
if({1,2,3,4}_v.contains(someval ))

しかし、リテラルを次のように定義しようとすると:

std::vector<int> operator"" _v ( std::initializer_list<int> t )
{
    return std::vector<int> (t);
}

取得した int のイニシャライザ リストを受け入れる

 error: 'std::vector<int> operator"" _v(std::initializer_list<int> t)' has invalid argument list

これを行う方法はありますか?私が本当に欲しいのは、最終的に次のようなものを取り除くことです

if(value == 1 || value ==2 || value == 3 ...

このようなものを書かなければならないのは本当に面倒です。

if value in (value1, value2 ...) 

または似たようなもの。

4

3 に答える 3

7

これはどう:

#include <initializer_list>

template <typename T>
bool contains(std::initializer_list<T> const & il, T const & x)
{
    for (auto const & z : il) { if (z == x) return true; }
    return false;
}

使用法:

bool b = contains({1, 2, 3}, 5);  // false
于 2013-01-16T22:03:49.963 に答える
6

あなたは構文が

if value in (value1, value2 ...) 

または似たようなもの。

文字を 1 つ追加する場合は、次の構文を試してください。

#include <algorithm>
#include <iostream>
#include <array>

template <typename T0, typename T1, std::size_t N>
bool operator *(const T0& lhs, const std::array<T1, N>& rhs) {
  return std::find(begin(rhs), end(rhs), lhs) != end(rhs);
}

template<class T0, class...T> std::array<T0, 1+sizeof...(T)> in(T0 arg0, T...args) {
  return {{arg0, args...}};
}

int main () {
  if( 2 *in(1,2,3) ) { std::cout << "Hello\n"; }
  if( 4 *in(5,6,7,8) ) { std::cout << "Goodbye\n"; }
}
于 2013-01-17T02:48:37.723 に答える
4

§13.5.8/3 は次のように述べています。

リテラル演算子の宣言には、次のいずれかと同等の parameter-declaration-clause が必要です。

const char*
unsigned long long int
long double
char
wchar_t
char16_t
char32_t
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t

initializer_listそのため、タイプのパラメーターを持つことはできないようです。

明らかなことは代替案としてしか考えられません。もう少し入力しても構わない場合は、次のようなことができます

std::vector<int> v(std::initializer_list<int> l) {
    return { l };
}

int someval = 1;
if(v({1,2,3,4}).contains(someval))

別の方法として、気まぐれになって次の演算子のオーバーロードを作成することもできますinitializer_list(まだテストしていません)。

bool operator<=(std::intializer_list<int> l, int value) {
    return std::find(std::begin(l), std::end(l), value) != std::end(l);
}

if ({1, 2, 3, 4} <= 3)

動作するはずです...

実際、気にしないでください。通常の機能を使用する必要があります。

于 2013-01-16T21:55:47.003 に答える