我寫一個函數inListi(),它至少需要一個參數,第一個參數的所有後續參數THES列表進行比較。如果第一個參數==列表中的元素則返回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個部分成一個字符串,然後再繼續。我想這樣做,因爲我可能會傳遞一個非空終止的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.
通知,即沒有中間代碼的被調用時,它直接使用通用版本。另外,看起來很奇怪的另一件事是'PKc'。我假設的是鍵入char *。現在,它爲什麼會有不同的類型?
不管怎麼說,謝謝!
感謝您的及時響應。我通過聲明兩個字符串局部變量併爲它們分配第一個和第二個參數來修改此代碼。該代碼確實被調用,但(字符串,字符串,休息)代碼不會被調用,而是跳轉到通用版本。所以(string,string,rest)中的to_lower代碼永遠不會被調用。有什麼建議麼? – Bitdiot
嘗試添加(字符串,字符串)重載。 –
再次感謝。我在原始代碼中有一個(字符串,字符串,休息)版本。但是我添加了一個(字符串,字符串)版本而沒有其餘的,它仍然調用通用代碼。 – Bitdiot