Question

Here the first function compiles and auto converts c char array to c++ string on input, but when I try to generalize that function on other types using template it becomes 'stupid' and says that it do not understand the type.

Is it possible with templates to make functions auto convert from char* to std::string and from w_chart* to std::wstring automatically just as it is happening with plain function definitions ?

#include <iostream>
#include <vector>
#include <string>

using namespace std;
vector<string> my_vector = { "apples", "bananas", "peaches"};

bool vector_has_item1(vector<string> v, string value_to_check) {
  for (string s : v) {
    if (s == value_to_check) return true;
  }
  return false;
}

template <typename T>
bool vector_has_item2(vector<T> v, T value_to_check) {
  for (T s : v) {
    if (s == value_to_check) return true;
  }
  return false;
}

int main() {
  cout << vector_has_item1(my_vector, "bananas") << endl;
  cout << vector_has_item2(my_vector, "bananas") << endl;
}

Error is:

test.cpp:25:48: error: no matching function for call to
 'vector_has_item2(std::vector<std::basic_string<char> >&, const char [8])'
Was it helpful?

Solution

Instead of letting the type T be determined from the second parameter, utilize the builtin typedefs in vector to force T to be determined from the first parameter and force the type of the second parameter to be determined from the first:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;
vector<string> my_vector = { "apples", "bananas", "peaches"};

bool vector_has_item1(vector<string> v, string value_to_check)
{
    return std::find(v.begin(), v.end(), value_to_check) != v.end();
}

template <typename T>
bool vector_has_item2(vector<T> v, typename vector<T>::value_type value_to_check)
{
    return std::find(v.begin(), v.end(), value_to_check) != v.end();
}

int main()
{
  cout << vector_has_item1(my_vector, "bananas") << endl;
  cout << vector_has_item2(my_vector, "bananas") << endl;
}

OTHER TIPS

Implicit conversions (*) are not allowed for parameters whose types depend on template parameters that participate in template parameter deduction (see C++11 §14.8.2.1/4).

Therefore, when deducing template parameters for

template <typename T>
bool vector_has_item2(vector<T> v, T value_to_check)

T cannot be deduced as std::string because the second argument is not of type std::string, nor a less cv-qualified version of std::string, nor a derived class of std::string. On the other hand, the non-template function

bool vector_has_item3(vector<string> v, string value_to_check)

could indeed be called with the arguments my_vector and "bananas" without any problem, because no template parameter deduction is involved, and an implicit conversion is performed on "bananas" in order to initialize the parameter value_to_check.

(*) Most implicit conversions, anyway---and certainly all user-defined conversions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top