少なくとも1つの引数を取り、最初の引数を後続のすべての引数のリストと比較する関数inListi()を作成しています。最初の引数==リスト内の要素の場合はtrueを返し、それ以外の場合はfalseを返します。それで:
if( inListi( 1.2, 2.3, 4.5, 1.2))
std::cout << "Returns true because last argument equals the first argument." << endl;
if( inListi( "hello", "world", "HEllo"))
std::cout << "This should print out because of the last argument." << endl;
問題は、それが機能しないことです。私は以下のコードを持っています。char [N]の場合、続行する前に配列のN個の部分を文字列にコピーします。nullで終了しないchar[N]が渡される可能性があるため、これを実行したいと思います。
とにかく、コードは以下の通りです。ほとんどのコードは冗長であり、constと、const[N]である引数とそのタイプではない引数の組み合わせを処理します。(ちなみに、この繰り返しを減らす方法はありますか?)
#include <iostream>
#include <stdexcept>
#include <string>
#include <sstream>
#include <typeinfo>
#include <type_traits>
#include <boost/algorithm/string.hpp>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// inListi
////////////////////////////////////////////////////////////////////////////////
template<typename T>
bool inListi(T&& value)
{
return false;
}
template<typename FirstType, typename SecondType, typename ... Rest>
bool inListi(FirstType&& first, SecondType&& second, Rest ... rest)
{
cout << "GENERIC inListi" << endl;
cout << "first is " << typeid(first).name() << endl;
cout << "second is " << typeid(second).name() << endl;
if( first == second)
return true;
else return inListi( first, rest...);
}
// We specialize the inListi for strings. We lower the case.
// but what if char[n] is passed? We have specializations that
// convert that to strings.
template<typename ... Rest>
bool inListi( string &&first, string &&second, Rest ... rest) {
string lFirst = first;
string lSecond = second;
cout << "LOWERED" << endl;
boost::algorithm::to_lower( lFirst);
boost::algorithm::to_lower( lSecond);
if( lFirst == lSecond)
return true;
else return inListi( first, rest...);
}
// Specializations for when we are given char-arrays. We copy the
// the arrays into a string upto the size of the array. This is done
// to take care of the case of when the char-array is not nul-terminated.
// The amount repetition is to permutate over which argument is a char-array
// and also for const-ness.
template<int F, typename SecondType, typename ... Rest>
bool inListi( char (&&first)[F], SecondType &&second, Rest ... rest) {
string strFirst = string( first, F);
cout << "arr, type, rest" << endl;
return inListi( strFirst, second, rest...);
}
template<int F, typename SecondType, typename ... Rest>
bool inListi( const char (&&first)[F], SecondType &&second, Rest ... rest) {
string strFirst = string( first, F);
cout << "const arr, type, rest" << endl;
return inListi( strFirst, second, rest...);
}
template<typename FirstType, int S, typename ... Rest>
bool inListi( FirstType &&first, char (&&second)[S], Rest ... rest) {
string strSecond = string( second, S);
cout << "type, arr, rest" << endl;
return inListi( first, strSecond, rest...);
}
template<typename FirstType, int S, typename ... Rest>
bool inListi( FirstType &&first, const char (&&second)[S], Rest ... rest) {
string strSecond = string( second, S);
cout << "type, const arr, rest" << endl;
return inListi( first, strSecond, rest...);
}
template<int F, int S, typename ... Rest>
bool inListi( char (&&first)[F], char (&&second)[S], Rest ... rest) {
string strFirst = string( first, F);
string strSecond = string( second, S);
cout << "arr, arr, rest" << endl;
return inListi( strFirst, strSecond, rest...);
}
template<int F, int S, typename ... Rest>
bool inListi( const char (&&first)[F], char (&&second)[S], Rest ... rest) {
string strFirst = string( first, F);
string strSecond = string( second, S);
cout << "const arr, arr, rest" << endl;
return inListi( strFirst, strSecond, rest...);
}
template<int F, int S, typename ... Rest>
bool inListi( char (&&first)[F], const char (&&second)[S], Rest ... rest) {
string strFirst = string( first, F);
string strSecond = string( second, S);
cout << "arr, const arr, rest" << endl;
return inListi( strFirst, strSecond, rest...);
}
template<int F, int S, typename ... Rest>
bool inListi( const char (&&first)[F], const char (&&second)[S], Rest ... rest) {
string strFirst = string( first, F);
string strSecond = string( second, S);
cout << "const arr, const arr, rest" << endl;
return inListi( strFirst, strSecond, rest...);
}
int main() {
if( inListi( "Hello", "World", "HEllo"))
cout << "Hello is in the listi." << endl;
else
cout << "Hello is not in the listi." << endl;
return 0;
}
プログラムの出力は次のとおりです。
[bitdiot foo]$ g++ forStackOverflow.cpp -std=gnu++0x
[bitdiot foo]$ ./a.out
GENERIC inListi
first is A6_c
second is A6_c
GENERIC inListi
first is A6_c
second is PKc
Hello is not in the listi.
中間コードは呼び出されないことに注意してください。汎用バージョンを使用することになります。また、奇妙に見えるもう1つのものは「PKc」です。私が想定しているのはchar*型です。さて、なぜそれは異なるタイプを持っているのでしょうか?
とにかく、ありがとう!