Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
std::string不能与std::set一起使用 我正在做一个C++编程语言的编程问题,它要求我制作一个模板 函数,该函数返回数组中唯一元素的数目。我不明白为什么 第13行导致编译时出错据我所知,std::string的行为类似于数组_C++_String_Set - Fatal编程技术网

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