[英]std::string not working with std::set
我正在從C ++ Primer Plus做一個編程問題,請我制作一個模板
該函數返回數組中唯一元素的數量。 我不明白為什么
據我所知,第13行在編譯時會導致錯誤,std :: string的行為類似於數組。
這是我的代碼:
#include <iostream>
#include <set>
template <typename T>
int reduce(T ar[], int n);
int main()
{
long test[] = {1, 2, 1, 3, 3, 4, 1};
std::string testStr = "testing";
std::cout << reduce(test, 6) << std::endl;
std::cout << reduce(testStr, 7) << std::endl;
std::cin.get();
return 0;
}
template <typename T>
int reduce(T ar[], int n)
{
std::set<T> test;
for(int i = 0; i < n; i++)
{
test.insert(ar[i]);
}
return test.size();
}
跟進我的立即反應,即std::string
不是數組,這是C ++人員可能會完成您正在尋找的任務的方式。
#include <iterator>
#include <iostream>
#include <set>
// instead of taking an array and length, just take where you want to start and where
// you want to stop.
template <typename TForwardIterator>
int reduce(TForwardIterator iter, TForwardIterator end)
{
// This is hideous syntax to get the type of object the iterator is describing.
// For std::string, it is char...for T*, it is T.
// I apologize for C++, I'm not sure there is a better way to do this.
typedef typename std::iterator_traits<TForwardIterator>::value_type value_type;
std::set<value_type> set;
// instead of forcing the objects to be an array type, use iterators!
for (; iter != end; ++iter)
set.insert(*iter);
return set.size();
}
int main()
{
long test[] = {1, 2, 1, 3, 3, 4, 1};
std::string testStr = "testing";
// begin() and end() are iterators you'll find on all the container types
std::cout << reduce(testStr.begin(), testStr.end()) << std::endl;
// pointers are iterators, too!
std::cout << reduce(test, test + 7) << std::endl;
return 0;
}
答案很簡單: std::string
不是數組。
就可以使用[]運算符訪問元素而言,它的行為就像一個數組,但它與char[]
數據類型根本不同。 事實上,該標准甚至不能保證它像數組一樣存儲(連續)。 T[]
將僅匹配到的數組,而不匹配可用於類數組的對象。
為了解決這個問題,您有幾種選擇
reduce(teststr.c_str(), 7)
,因為c_str()
將返回帶有字符串內容的chararray。 reduce
重寫為template <typename T, typename U> int reduce(U ar, int n)
並將其稱為reduce<long>(test, 6)
和reduce<char>(testStr, 7)
。 第二個模板參數是必需的,因為沒有從容器到元素的統一方法(在c ++ 0x /使用編譯器擴展中除外)。 template <typename T>int reduce(T ar, int n)
和std::set<decltype(ar[0])> test;
(代碼的其余部分保持不變,並且我似乎在代碼塊部分遇到了麻煩,因此這里只有這兩行。 當然,在c ++中,通常會用迭代器的形式編寫這樣的函數(請參見Travis Gockels的答案),因為這只是一種更靈活且得到更好支持的方式。
您可能會將std :: strings與內置字符數組混淆。 std :: strings不是數組,盡管它們的行為類似於數組(類具有重載的[]運算符)並包含數組(您可以通過c_str()訪問)。
如果將第10行替換為
char testStr[] = "testing";
您的程序將編譯並運行。
或者,您可以嘗試執行以下操作:
#include <iostream>
#include <set>
template <typename T>
int reduce(const T* ar, int n);
int main()
{
long test[] = {1, 2, 1, 3, 3, 4, 1};
std::string testStr = "testing";
std::cout << reduce(test, 7) << std::endl;
std::cout << reduce(testStr.c_str(), testStr.size()) << std::endl;
std::cin.get();
return 0;
}
template <typename T>
int reduce (const T* ar, int n)
{
std::set<T> test;
for(int i = 0; i < n; i++)
{
test.insert(ar[i]);
}
return test.size();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.