2016-03-15 11 views
7

2つのパラメータt1とt2を使用する次の例があります。2つ以上のパラメータを持つバリデリックテンプレート関数

template<typename T> 
bool Compare(T t1, T t2) 
{ 
    return t1 == t2; 
} 

template<typename T, typename... Args> 
bool Compare(T t1, T t2, Args... args) 
{ 
    return (t1 == t2) && Compare(args...); 
} 

int main(void) 
{ 
    Compare(1, 1, "string", "string"); 
} 

機能比較は、同じタイプであり比較可能なパラメータのペアを取ります。 2つのペアが比較され、最後の2つのパラメータに達するまで、パラメータパックが再帰的に渡されます。 再帰を停止するには、パラメータパックなしでCompare関数の実装を使用します。私は関数は比較に第3引数T3を追加したいと思います

は次のようにする必要があります:

template<typename T> 
bool Compare(T t1, T t2, T t3) 
{ 
    return t1 == t2 == t3; 
} 

template<typename T, typename... Args> 
bool Compare(T t1, T t2, T t3, Args... args) 
{ 
    return (t1 == t2 == t3) && Compare(args...); 
} 

int main(void) 
{ 
    Compare(1, 1, 1, "string", "string", "string"); 
} 

私は、この関数は、次の3を再帰的に処理されている比較に3つのパラメータを取ることを期待しています。私はこのコードをコンパイルしようとする 私は次のエラーを取得:同じ種類の3つのパラメータセットを比較するために、この機能を実装する方法を

>xxx\source.cpp(4): error C2446: '==': no conversion from 'const char *' to 'int' 
1> xxx\source.cpp(4): note: There is no context in which this conversion is possible 
1> xxx\source.cpp(10): note: see reference to function template instantiation 'bool Compare<const char*>(T,T,T)' being compiled 
1>   with 
1>   [ 
1>    T=const char * 
1>   ] 
1> xxx\source.cpp(15): note: see reference to function template instantiation 'bool Compare<int,const char*,const char*,const char*>(T,T,T,const char *,const char *,const char *)' being compiled 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>xxx\source.cpp(4): error C2040: '==': 'int' differs in levels of indirection from 'const char *' 

t1t2t3が全て等しいかどうかをチェックしない

答えて

8
t1 == t2 == t3 

boolt3に等しい場合、t1t2に等しい場合、それはチェックし、次にチェックします。

たぶん、何を代わりにしたいことさ(と仮定し、合理的な等価演算子):

t1 == t2 && t1 == t3 

だからあなたのコードは次のようになります。文字列リテラルを使用してテストコールがポインタの比較を行い

template<typename T> 
bool Compare(T t1, T t2, T t3) 
{ 
    return t1 == t2 && t1 == t3; 
} 

template<typename T, typename... Args> 
bool Compare(T t1, T t2, T t3, Args... args) 
{ 
    return t1 == t2 && t1 == t3 && Compare(args...); 
} 

注意これはあなたが望むものではないかもしれません。

+0

最後の行を展開するには: "string"を含むstd文字列のc_str()を引数の1つとして渡すと、すべての文字列が "string" 。可能であれば、std文字列(その中に文字列定数をラップする文字列も含む)を使用するほうがよいでしょう。 –

0

これは私のより一般的な解決策です。 compareConsecutive<N>は、N個の連続する引数がすべてN個の引数のブロックで等しい場合にのみtrueを返します。

#include <iostream> 
#include <tuple> 
#include <utility> 

template <std::size_t Start, typename IndexSequence> struct MakeIndexSequenceHelper; 

template <std::size_t Start, std::size_t... Is> 
struct MakeIndexSequenceHelper<Start, std::index_sequence<Is...>> { 
    using type = std::index_sequence<(Start + Is)...>; 
}; 

template <std::size_t Start, std::size_t Length> 
struct MakeIndexSequence : MakeIndexSequenceHelper<Start, std::make_index_sequence<Length>> {}; 

template <typename T, typename U> 
bool allAreSame (const T&, const U&) { 
    return false; 
} 

template <typename T> 
bool allAreSame (const T& t1, const T& t2) { 
    return t1 == t2; 
} 

template <typename T, typename U, typename... Args> 
bool allAreSame (const T&, const U&, const Args&...) { 
    return false; 
} 

template <typename T, typename... Args> 
bool allAreSame (const T& t1, const T& t2, const Args&... args) { 
    return allAreSame(t1, t2) && allAreSame(t1, args...); 
} 

template <typename Tuple, std::size_t... Is> 
bool allAreSameHelper (Tuple&& tuple, std::index_sequence<Is...>) { 
    return allAreSame (std::get<Is>(std::forward<Tuple>(tuple))...); 
} 

template <std::size_t N, typename... Args> 
bool allAreSameHelper (Args&&... args) { 
    return allAreSameHelper (std::forward_as_tuple(std::forward<Args>(args)...), std::make_index_sequence<N>{}); 
} 

template <std::size_t N, typename... Args> bool compareConsecutive (Args&&...); 

template <std::size_t N> 
bool compareConsecutive() {return true;} 

template <std::size_t N, typename Tuple, std::size_t... Is> 
bool compareConsecutiveHelper (Tuple&& tuple, std::index_sequence<Is...>) { 
    return compareConsecutive<N> (std::get<Is>(std::forward<Tuple>(tuple))...); 
} 

template <std::size_t N, std::size_t Start, std::size_t Length, typename... Args> 
bool compareConsecutiveHelper (Args&&... args) { 
    return compareConsecutiveHelper<N> (std::forward_as_tuple(std::forward<Args>(args)...), typename MakeIndexSequence<Start, Length>::type{}); 
} 

template <std::size_t N, typename... Args> 
bool compareConsecutive (Args&&... args) { 
    return allAreSameHelper<N>(std::forward<Args>(args)...) && compareConsecutiveHelper<N, N, sizeof...(Args) - N>(args...); 
} 

int main() { 
    std::cout << std::boolalpha << allAreSame("hi", "hi", "hi", "hi", "hi", "hi") << '\n'; // true 
    std::cout << compareConsecutive<2>(1, 1, "hi", "hi") << '\n'; // true 
    std::cout << compareConsecutive<2>(1, "hi", "hi", "hi") << '\n'; // false 
    std::cout << compareConsecutive<3>(1, 1, 1, "hi", "hi", "hi", 4.5, 4.5, 4.5) << '\n'; // true 
    std::cout << compareConsecutive<5>(1, 1, 1, 1, 1, "hi", "hi", "hi", "hi", "hi") << '\n'; // true 
    std::cout << compareConsecutive<5>(1, 1, 1, 1, 2, "hi", "hi", "hi", "hi", "hi") << '\n'; // false 
} 
関連する問題