8

重複の可能性:
一連の値を特定の値と比較する C++

C++ の for ループで等価性をチェックする必要がありますが、複数の可能性に等しい x に対してループが機能する必要があります。

たとえば、現在、次のようなものがあります。

if(x==a || x==b || x==c || x==d || x==e || x==f || x==g || x==h)
{
    //loop body
}

しかし、私が持っている数では、それは乱雑に見え、「if (x == (これらのいずれか))」と言う簡単な方法があるのか​​ 、それともすべてを書き出すことが唯一のオプションなのか疑問に思っていました.

ありがとう!

4

3 に答える 3

4

ご質問ありがとうございます。解決策を見つけたので(そして私が敢えて言うエレガントなもの)、私はそれを自分で使用します。

std :: findを使用したソリューションとは異なり、a)コンパイル時にN個の比較に展開されますb)Xを比較できる任意のタイプで機能します

struct TagAnyOf {};

template <typename... Args>
std::tuple <TagAnyOf, Args...> AnyOf (Args&&... args)
{
   return std::tuple <TagAnyOf, Args...> (TagAnyOf(), std::forward<Args>(args)...);
}

template <class X, class Tuple, size_t Index, size_t ReverseIndex>
struct CompareToTuple
{
    static bool compare (const X& x, const Tuple& tuple)
    {
        return x == std::get<Index> (tuple) || CompareToTuple<X, Tuple, Index+1, ReverseIndex-1>::compare (x, tuple);
    }
};

template <class X, class Tuple, size_t Index>
struct CompareToTuple <X, Tuple, Index, 0>
{
    static bool compare (const X& x, const Tuple& tuple)
    {
        return false;
    }
};

template <typename X, typename... Args>
bool operator == (const X& x, const std::tuple<TagAnyOf, Args...>& any)
{
    typedef std::tuple <TagAnyOf, Args...> any_of_type;
    return CompareToTuple <X, any_of_type, 1, std::tuple_size<any_of_type>::value-1>::compare (x, any);
}

使用法

int main()
{
    int x = 1;
    if (x == AnyOf (1, 2, 3, 4))
    {
        std::cout << "Yes!" << std::endl;
    }
    else
    {
        std::cout << "No!" << std::endl;
    }

    if (x == AnyOf (4, 3, 2, 1))
    {
        std::cout << "Yes!" << std::endl;
    }
    else
    {
        std::cout << "No!" << std::endl;
    }

    if (x == AnyOf (2, 3, 4, 5))
    {
        std::cout << "Yes!" << std::endl;
    }
    else
    {
        std::cout << "No!" << std::endl;
    }

    return 0;
}
于 2012-11-04T00:22:27.933 に答える
2

initializer_list を取る関数の使用を検討してください (これは c++11 の機能です)。
最初のパラメーターは左側の値 (この場合は x) になり、残りのパラメーターは右側の値になります。


テンプレートを使用してタスクを実行する例を次に示します。

#include <iostream>
#include <cstdlib>
#include <algorithm>

template<class T> 
bool Test(T const& test, std::initializer_list<T> const& values){
    return std::find(std::begin(values), std::end(values), test) != std::end(values);
}

int main(){

    char var1 = 'a';
    char var2 = 'a';
    char var3 = 'b';
    char var4 = 'c';
    char var5 = 'd';

    if (Test<char>(var1,{var2,var3,var4,'o',var5})){
        std::cout << "true. at least one is equivelent" << std::endl;
    }else{
        std::cout << "false. none are equivelent" << std::endl;
    }

    if (Test<char>(var1,{var3,var4,var5})){
        std::cout << "true. at least one is equivelent" << std::endl;
    }else{
        std::cout << "false. none are equivelent" << std::endl;
    }

    return EXIT_SUCCESS;
}

クラスでこれを行う場合は、必ず「!=」演算子をオーバーロードしてください。

編集:間違いを修正しました。GManNickG によって指摘されました

于 2012-11-03T23:35:17.170 に答える
0

「if (x == (これらのいずれか))」という簡単な言い方があるかどうか疑問に思っていました。

はい、標準では、この質問に正確に答えることができstd::findますstd::find_if

int a=3,b=5,c=6,d=7;
std::array<int,4> vals{{a,b,c,d}}; // or std::vector
int x=5;
bool foundit= (end(vals) != std::find_if(begin(vals), end(vals),x );

必要になるだろう

#include <array>
#include <algorithm>

またはstd::initializer_list<int> booleans{a,b,c,d};の代わりに使用することもできますvectorarray

条件がより複雑な場合は、find_if を使用できます。

 bool foundit= (end(vals) != 
               std::find_if(begin(vals), end(vals),
                            [&x](const int &v){return v*(v+x)<x;}));
于 2012-11-04T00:06:06.320 に答える