質問

I am a newbie in C++ and trying to finish the C++ assignment. In the code question, I cannot change anything in the main function but could add code outside the main function.

Here is the main:

int main()
{
    MySet<int> stInt;
    int a[100];


    int n;
    cin >> n;
    for(int i = 0;i < n; ++i )
        cin >> a[i];
    MySet<int> stInt(a,a+n);
    MyPrint(stInt.begin(),stInt.end());
    cout << endl;
    int s,e;
    cin >> s >> e; 
    pair<MySet<int>::iterator, MySet<int>::iterator> p;
    p  = stInt.FindInterval(s,e);
    if( p.first != p.second) 
    {
        MyPrint(p.first,p.second);
        cout << endl;
    }
    else
       cout << "Interval Not Found" << endl;
    cin >> n;
    MySet<double,greater<double> > stDouble;
    for( int i = 0;i < n; ++i)  
    {
         double d;
         cin >> d;
         stDouble.insert(d);
    }
    MyPrint(stDouble.begin(),stDouble.end());
    cout << endl;
    double w;
    cin >> w;
    cout << * stDouble.upper_bound(w) << endl;

 return 0;
 }

To get the correct answer, my thought is to create a new STL class named MySet, which is inherited from STL set, and it seems the MyPrint() function has some bugs. I really have no idea what this is.

BTW, I compile the code in VS2010 Pro. The bug info is:

unresolved external symbol "void __cdecl MyPrint(class std::_Tree_const_iterator,class std::allocator,0> > >,class std::_Tree_const_iterator,class std::allocator,0> > >)" (?MyPrint@@YAXV?$_Tree_const_iterator@V?$_Tree_val@V?$_Tset_traits@NU?$less@N@std@@V?$allocator@N@2@$0A@@std@@@std@@@std@@0@Z) referenced in function _main

And my snippet is:

template<typename T, class Compare = less<T>, class Alloc = allocator<T> >
class MySet:public set<T>
{
private:
    T st[100];
public:
    MySet():set<T>() {}
    MySet(int *first, int *last)
    {
        int *idx = first;
        for(int i = 0; idx <= last; ++idx, ++i)
            st[i] = *idx;
    }

    pair<typename set<T>::iterator, typename set<T>::iterator>FindInterval(int lower,   int upper)
    {
        typename set<T>::iterator low, up;
        low = lower_bound(lower);
        up = upper_bound(upper);
        return (pair<typename set<T>::iterator, typename set<T>::iterator>(low, up));

    }
    void friend MyPrint(typename set<T>::iterator first_, typename set<T>::iterator last_);


};

template<typename T>
void MyPrint(typename MySet<T>::iterator first_, typename MySet<T>::iterator last_)
{
typename MySet<T>::iterator it = first_;
for(; it != last_; ++it)
    cout << *it << " ";
}

The MyPrint() function just prints all the elements in MySet.

I have asked all the people knowing C++ but it seems they cannot help me... And I am stuck for more than 3 days....

Thanks!

Yiru

役に立ちましたか?

解決

Your program declares two functions - or rather, two families of functions - named MyPrint. First, there is a set of non-template friend functions, one for each instantiation of MySet template. Second, there is a set of instantiations of MyPrint template. But you only provide the actual implementation for the second set.

For MyPrint call in main, both sets are viable candidates, and other things equal, the compiler prefers non-template to a template. Then the linker discovers that the non-template lacks implementation.

There are two ways around it. You could either implement the non-template in-class, and drop the template:

template <typename T>
class MySet {
  friend void MyPrint(...) { ... }
};

Or you could befriend the template, and drop the non-template:

template <typename T>
void MyPrint(typename set<T>::iterator, typename set<T>::iterator);

template <typename T>
class MySet {
  friend void MyPrint<T>(typename set<T>::iterator, typename set<T>::iterator);
};

template <typename T>
void MyPrint(typename set<T>::iterator, typename set<T>::iterator)
{ ... }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top