std::string不能与std::set一起使用 我正在做一个C++编程语言的编程问题,它要求我制作一个模板 函数,该函数返回数组中唯一元素的数目。我不明白为什么 第13行导致编译时出错据我所知,std::string的行为类似于数组
这是我的代码:std::string不能与std::set一起使用 我正在做一个C++编程语言的编程问题,它要求我制作一个模板 函数,该函数返回数组中唯一元素的数目。我不明白为什么 第13行导致编译时出错据我所知,std::string的行为类似于数组,c++,string,set,C++,String,Set,这是我的代码: #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) <<
#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();
}
#包括
#包括
样板
int-reduce(tar[],int-n);
int main()
{
长测试[]={1,2,1,3,3,4,1};
std::string testStr=“testing”;
std::cout答案很简单:std::string
不是数组
就您可以使用[]运算符访问元素而言,它的行为类似于数组,但它与char[]
的数据类型不同。事实上,标准甚至不能保证它像数组一样存储(意思是连续存储)。t[]
将仅匹配的数组,而不是可以像数组一样使用的对象
为了解决这个问题,你有几个选择
您可以调用reduce(teststr.c_str(),7)
,因为c_str()
将返回包含字符串内容的字符集
您可以将reduce
重写为template int-reduce(U-ar,int-n)
并将其称为reduce(test,6)
和reduce(testStr,7)
。第二个模板参数是必需的,因为没有从容器到元素的统一方法(使用编译器扩展名的c++0x/中除外)
如果您使用的是c++0x,那么您可以使用decltype从容器获取包含的元素:template int reduce(tar,int n)
和std::set test;
(代码的其余部分保持不变,不知怎的,我似乎在代码块部分上遇到了问题,所以这里只有这两行代码
<>当然,C++中通常会用迭代器来编写这样的函数(参见Travis Gockels回答),因为这只是一种更灵活和更好的支持方式。 < P>答案很简单:<代码> STD::String < /C> >不是数组。< /P>
就您可以使用[]运算符访问元素而言,它的行为类似于数组,但它与char[]
的数据类型不同。事实上,标准甚至不能保证它像数组一样存储(意思是连续存储)。t[]
将仅匹配的数组,而不是可以像数组一样使用的对象
为了解决这个问题,你有几个选择
您可以调用reduce(teststr.c_str(),7)
,因为c_str()
将返回包含字符串内容的字符集
您可以将reduce
重写为template int-reduce(U-ar,int-n)
并将其称为reduce(test,6)
和reduce(testStr,7)
。第二个模板参数是必需的,因为没有从容器到元素的统一方法(使用编译器扩展名的c++0x/中除外)
如果您使用的是c++0x,那么您可以使用decltype从容器获取包含的元素:template int reduce(tar,int n)
和std::set test;
(代码的其余部分保持不变,不知怎的,我似乎在代码块部分上遇到了问题,所以这里只有这两行代码
<>当然,C++中的一个典型的是用迭代器来写这样的函数(参见Travis Gockels回答),因为这只是一个更灵活和更好的支持方式。 跟踪我的即时响应:<>代码> 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;
}
#包括
#包括
#包括
//不需要获取数组和长度,只需获取您想要开始的位置和长度
//你想停下来。
样板
int reduce(TForwardIterator iter,TForwardIterator end)
{
//获取迭代器描述的对象类型是一种可怕的语法。
//对于std::string,它是char…对于T*,它是T。
/我为C++道歉,我不确定还有更好的方法来做这件事。
typedef typename std::迭代器特征::值类型值类型;
std::set;
//不要强迫对象成为数组类型,而是使用迭代器!
对于(;iter!=结束;++iter)
成套插入(*iter);
返回set.size();
}
int main()
{
长测试[]={1,2,1,3,3,4,1};
std::string testStr=“testing”;
//begin()和end()是在所有容器类型上都可以找到的迭代器
STD::CUT我立即回应,<代码> 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;
}
#包括
#包括
#包括
//不需要获取数组和长度,只需获取您想要开始的位置和长度
//你想停下来。
样板
int reduce(TForwardIterator iter,TForwardIterator end)
{
//获取迭代器描述的对象类型是一种可怕的语法。
//对于std::string,它是char…对于T*,它是T。
/我为C++道歉,我不确定还有更好的方法来做这件事。
typedef typename std::迭代器特征::值类型值类型;
std::set;
//不要强迫对象成为数组类型,而是使用迭代器!
对于(;iter!=结束;++iter)
成套插入(*iter);
返回set.size();
}
int main()
{
长测试[]={1,2,1,3,3,4,1};
std::string testStr=“testing”;
//begin()和end()是在所有容器类型上都可以找到的迭代器
std::cout您可能会将std::string与内置字符数组混淆。std::string不是数组,尽管它们的行为类似于数组(类具有重载的[]运算符)并包含数组(可以通过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();
}
#包括
#包括
样板
int reduce(常数T*ar,int n);
int main()
{
长测试[]={1,2,1,3,3,4,1};
std::string testStr=“testing”;
标准::cout