简体   繁体   中英

How to return boolean value from a template function?

In the following C++ code, I want to use a template function to determine if two vectors are exactly the same, but, I always get false from the template function. Would you give me suggestion about how to return boolean values from a template function? (My C++ compiler is g++ 4.6)

Edit: after pop_back both p1 p2 p3 p4, the results are now matched with what I expected.

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

template<class T> bool areTheyMatched(shared_ptr<vector<T>> p1, shared_ptr<vector<T>> p2) {
if ((*p1).size() == (*p2).size()) {
    cout << (*p1).size() << endl;
    for (unsigned int i = 0;  i < (*p1).size(); i++) {
      if ((*p1)[i] != (*p2)[i]) {
        cout << (*p1)[i] << " " <<  (*p2)[i] << endl;   
        return false;
          } 
        }
 } else {
    return false;
 }
 cout << "All elements are exactly the same" << endl;
 return true;
 }


 int main(int argc, char *argv[]) {
   shared_ptr<vector<int>> p1(new vector<int>);
   shared_ptr<vector<int>> p2(new vector<int>);
   shared_ptr<vector<double>> p3(new vector<double>);
   shared_ptr<vector<double>> p4(new vector<double>);
   for (int i = 0; i < 10; i++) 
     (*p1).push_back(i); 
   for (int i = 0; i < 9; i++) 
     (*p2).push_back(i);
   (*p2).push_back(11);
   for (double i = 0.0; i < 9.9; i += 1.1) 
      (*p3).push_back(i);
   for (double i = 0.0; i < 8.8; i += 1.1) 
      (*p4).push_back(i);
   (*p4).push_back(11.0);
   cout << "Case 1: " << areTheyMatched(p1, p2) << endl;
   (*p1).pop_back();
   (*p2).pop_back();
   cout << "Case 2: " << areTheyMatched(p1, p2) << endl;
   cout << "Case 3: " << areTheyMatched(p3, p4) << endl;
   (*p3).pop_back();
   (*p4).pop_back();
   cout << "Case 4: " << areTheyMatched(p3, p4) << endl;
   p1.reset();
   p2.reset();
   p3.reset();
   p4.reset();
   return 0;
}

The template code seems fine, but the test vectors just never are the same, are they.

First they differ in one of them having the element 11, and when removing that they have different sizes.

Your vectors are realy different.

   for (int i = 0; i < 10; i++) 
     (*p1).push_back(i); 
   for (int i = 0; i < 9; i++) 
     (*p2).push_back(i);
   (*p2).push_back(11);

p1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
p2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 11}
Case 1: false
(*p2).pop_back();
p1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
p2 = {0, 1, 2, 3, 4, 5, 6, 7, 8}
Case 2: false

Your template function is totally fine...

The reason you're getting false is because your inputs really are different, initially in content, and after the pop even the size doesn't match.

Is there a reason why you're using shared_ptr? You could pass vector& and unless you need shared pointers for a good reason, you shouldn't use them. Although they are the best way to pass pointers around when you need to share data across many entities, they have an overhead.

If you instrument the code, you'll see that it works correctly. I needed to use std::tr1 and <tr1/memory> and > > instead of >> to get it to compile with G++ 4.6.1, but this shows it working:

#include <iostream>
#include <tr1/memory>
#include <vector>

using namespace std;
using namespace std::tr1;

template<class T> bool areTheyMatched(shared_ptr< vector<T> > p1, shared_ptr< vector<T> > p2)
{
    cout << "p1.size: " << (*p1).size() << ", p2.size: " << (*p2).size() << endl;
    if ((*p1).size() != (*p2).size())
        return false;
    for (unsigned int i = 0;  i < (*p1).size(); i++)
    {
        if ((*p1)[i] != (*p2)[i])
        {
            cout << "i = " << i << ": " << (*p1)[i] << " " <<  (*p2)[i] << endl;   
            return false;
        }
    }
    cout << "All elements are exactly the same" << endl;
    return true;
}

int main()
{
   shared_ptr< vector<int> > p1(new vector<int>);
   shared_ptr< vector<int> > p2(new vector<int>);
   shared_ptr< vector<double> > p3(new vector<double>);
   shared_ptr< vector<double> > p4(new vector<double>);
   for (int i = 0; i < 10; i++) 
     (*p1).push_back(i); 
   for (int i = 0; i < 9; i++) 
     (*p2).push_back(i);
   (*p2).push_back(11);
   for (double i = 0.0; i < 9.9; i += 1.1) 
      (*p3).push_back(i);
   for (double i = 0.0; i < 8.8; i += 1.1) 
      (*p4).push_back(i);
   (*p4).push_back(11.0);

   cout << "Case 1: " << areTheyMatched(p1, p2) << endl;
   (*p2).pop_back();
   cout << "Case 2: " << areTheyMatched(p1, p2) << endl;
   (*p1).pop_back();
   cout << "Case 2a: " << areTheyMatched(p1, p2) << endl;

   cout << "Case 3: " << areTheyMatched(p3, p4) << endl;
   (*p3).pop_back();
   cout << "Case 4: " << areTheyMatched(p3, p4) << endl;
   (*p4).pop_back();
   cout << "Case 4a: " << areTheyMatched(p3, p4) << endl;
   p1.reset();
   p2.reset();
   p3.reset();
   p4.reset();
   return 0;
}

Output

p1.size: 10, p2.size: 10
i = 9: 9 11
Case 1: 0
p1.size: 10, p2.size: 9
Case 2: 0
p1.size: 9, p2.size: 9
All elements are exactly the same
Case 2a: 1
p1.size: 10, p2.size: 10
i = 9: 9.9 11
Case 3: 0
p1.size: 9, p2.size: 10
Case 4: 0
p1.size: 9, p2.size: 9
All elements are exactly the same
Case 4a: 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM