Home > Blockchain >  no overloaded function could convert all the argument types
no overloaded function could convert all the argument types

Time:12-15

I want to create a function Vec2() for the follow input:
string in="[[">>v","v^<","<><"],[">>v","v^<","<><"]]"
it should return
{{">>v","v^<","<><"},{">>v","v^<","<><"}}

It works fine in single string version,in that case ,stringToVecStr()gives the correct answer. ie: [">>v","v^<","<><"]->{">>v","v^<","<><"}

But for Vec2() it errors out:

'std::vector<std::vector<std::string, std::allocator<std::string>>, std::allocator<std::vector<std::string, std::allocator<std: :string>>>>::push_back':
  no overloaded function could convert all the argument types temp C:\Users\mingy\source\repos\temp\temp\Source.cpp 72

What does this mean and where should I modify it?

Here is a minimal reproducible example:

#include<iostream>
#include<string>
#include<type_traits>
#include<fstream>
#include<vector>
#include<regex>
#include<sstream>
using namespace std;

inline string stringToVecStr(const string input) {
  string result;
  for (int i = 1; i < input.length() - 1; i  ) {
    char currentChar = input[i];
    if (input[i] == '\\') {
      char nextChar = input[i   1];
      switch (nextChar) {
      case '\"': result.push_back('\"'); break;
      case '/': result.push_back('/'); break;
      case '\\': result.push_back('\\'); break;
      case 'b': result.push_back('\b'); break;
      case 'f': result.push_back('\f'); break;
      case 'r': result.push_back('\r'); break;
      case 'n': result.push_back('\n'); break;
      case 't': result.push_back('\t'); break;
      default: break;
      }
      i  ;
    }
    else {
      result.push_back(currentChar);
    }
  }
  return result;
}

const int32_t TREE_NODE_BOUNDNARY = INT_MIN   1; // replace null

//note:Vec() is to hanlde `vector<int>` such as `[1,2,3,4,5]`
//I put it here just for the completeness of the code, you can ignore it
template<typename T>
std::vector<T> Vec(const std::string inputStr)
{
  std::vector<T> ret;
  const std::string pattern = R"(([ |-]?\w*\.?[\w |#|(|)|\.]),?)";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    std::stringstream ss;
    std::string treeNull = match.str(1) == "null" ? std::to_string(TREE_NODE_BOUNDNARY) : match.str(1);
    ss << treeNull;
    T temp;
    ss >> temp;
    ret.push_back(temp);
    log = match.suffix();
  }
  if (ret.empty())
    std::cout << "Failed to construct Matrix" << std::endl;
  return ret;
}


template<typename T>
std::vector<std::vector<T>> Vec2(const std::string inputStr)
{
  std::vector<std::vector<T>> ret;
  const std::string pattern = R"((\[[^\[\]]*\]))";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    std::string vec = match.str(1);
    if (is_same_v<T, string>)
    {
      string temp = stringToVecStr(vec);
      ret.push_back(temp);
    }
    else {
      ret.push_back(Vec<T>(vec));
    }
    log = match.suffix();
  }

  if (ret.empty()) {
    std::cout << "Failed to construct Matrix" << std::endl;
  }
  return ret;
}

int main()
{
  std::string in1 = "[\">>v\",\"v^<\",\"<><\"]";
  auto t1 = stringToVecStr(in1);
  cout << t1;
  //cout << endl;

  std::string in2 = "[[\">>v\",\"v^<\",\"<><\"],[\">>v\",\"v^<\",\"<><\"]]";
  auto t2 = Vec2<string>(in2);
  for (auto i : t1)cout << i << " ";
  return 0;
}

It says It looks like your post is mostly code; please add some more details., but I really don't have anything to add.

Below is the full output:

1>------ Build started: Project: temp, Configuration: Debug x64 ------
1>Source.cpp
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(69,5): warning C4984: 'if constexpr' is a C  17 language extension
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,10): error C2665: 'std::vector<std::vector<std::string,std::allocator<std::string>>,std::allocator<std::vector<std::string,std::allocator<std::string>>>>::push_back': no overloaded function could convert all the argument types
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\vector(939,23): message : could be 'void std::vector<std::vector<std::string,std::allocator<std::string>>,std::allocator<std::vector<std::string,std::allocator<std::string>>>>::push_back(_Ty &&)'
1>        with
1>        [
1>            _Ty=std::vector<std::string,std::allocator<std::string>>
1>        ]
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,10): message : 'void std::vector<std::vector<std::string,std::allocator<std::string>>,std::allocator<std::vector<std::string,std::allocator<std::string>>>>::push_back(_Ty &&)': cannot convert argument 1 from 'std::string' to '_Ty &&'
1>        with
1>        [
1>            _Ty=std::vector<std::string,std::allocator<std::string>>
1>        ]
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,21): message : Reason: cannot convert from 'std::string' to '_Ty'
1>        with
1>        [
1>            _Ty=std::vector<std::string,std::allocator<std::string>>
1>        ]
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,21): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\vector(935,23): message : or       'void std::vector<std::vector<std::string,std::allocator<std::string>>,std::allocator<std::vector<std::string,std::allocator<std::string>>>>::push_back(const _Ty &)'
1>        with
1>        [
1>            _Ty=std::vector<std::string,std::allocator<std::string>>
1>        ]
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,10): message : 'void std::vector<std::vector<std::string,std::allocator<std::string>>,std::allocator<std::vector<std::string,std::allocator<std::string>>>>::push_back(const _Ty &)': cannot convert argument 1 from 'std::string' to 'const _Ty &'
1>        with
1>        [
1>            _Ty=std::vector<std::string,std::allocator<std::string>>
1>        ]
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,21): message : Reason: cannot convert from 'std::string' to 'const _Ty'
1>        with
1>        [
1>            _Ty=std::vector<std::string,std::allocator<std::string>>
1>        ]
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,21): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(72,10): message : while trying to match the argument list '(std::string)'
1>C:\Users\mingy\source\repos\temp\temp\Source.cpp(94,29): message : see reference to function template instantiation 'std::vector<std::vector<std::string,std::allocator<std::string>>,std::allocator<std::vector<std::string,std::allocator<std::string>>>> Vec2<std::string>(const std::string)' being compiled
1>Done building project "temp.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Thanks for the discussion everyone, I think I have achieved my intent correctly

#include<iostream>
#include<string>
#include<type_traits>
#include<fstream>
#include<vector>
#include<regex>
#include<sstream>
using namespace std;

inline vector<string> VecStr(const string input) {
  if (input.size() < 2) {
    std::cout << "Construct vector<string> failed" << std::endl;
    return{};
  }
  vector<string> res;
  string result;
  for (int i = 1; i < input.length() - 1; i  ) {
    char currentChar = input[i];
    if (input[i] == '\\') {
      char nextChar = input[i   1];
      switch (nextChar) {
      case '\"': result.push_back('\"'); break;
      case '/': result.push_back('/'); break;
      case '\\': result.push_back('\\'); break;
      case 'b': result.push_back('\b'); break;
      case 'f': result.push_back('\f'); break;
      case 'r': result.push_back('\r'); break;
      case 'n': result.push_back('\n'); break;
      case 't': result.push_back('\t'); break;
      default: break;
      }
      i  ;
    }
    else {
      result.push_back(currentChar);
    }
    if (input[i] == ',')
    {
      result.pop_back();
      result.pop_back();
      res.push_back(result.substr(1));
      result = "";
    }
  }
  if(!result.empty()){
    result.pop_back();
    res.push_back(result.substr(1));
  }
  return res;
}

const int32_t TREE_NODE_BOUNDNARY = INT_MIN   1; // replace null

inline std::vector<std::vector<string>> Vec2Str(const std::string inputStr)
{
  std::vector<std::vector<string>> ret;
  const std::string pattern = R"((\[[^\[\]]*\]))";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    const std::string vec = match.str(1);
    ret.push_back(VecStr(vec));
    log = match.suffix();
  }
  if (ret.empty()) std::cout << "Construct vector<vector<string>> failed" << std::endl;
  return ret;
}

//template for int and long long
template<typename T>
std::vector<T> Vec(const std::string inputStr)
{
  std::vector<T> ret;
  const std::string pattern = R"(([ |-]?\w*\.?[\w |#|(|)|\.]),?)";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    std::stringstream ss;
    std::string treeNull = match.str(1) == "null" ? std::to_string(TREE_NODE_BOUNDNARY) : match.str(1);
    ss << treeNull;
    T temp;
    ss >> temp;
    ret.push_back(temp);
    log = match.suffix();
  }
  if (ret.empty())
    std::cout << "Construct Vector failed" << std::endl;
  return ret;
}
template<typename T>
std::vector<std::vector<int>> Vec2(const std::string inputStr)
{
  std::vector<std::vector<T>> ret;
  const std::string pattern = R"((\[[^\[\]]*\]))";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    const std::string vec = match.str(1);
    ret.push_back(Vec<int>(vec));
    log = match.suffix();
  }
  if (ret.empty()) std::cout << "Construct failed" << std::endl;
  return ret;
}


int main()
{
  std::string in1 = "[\">>v\",\"v^<\",\"<><\"]";
  auto t1 = VecStr(in1);
  for (auto i : t1) cout << i << endl;

  std::string in2 = "[[\">>v\",\"v^<\",\"<><\"],[\">>v\",\"v^<\",\"<><\"]]";
  auto t2 = Vec2Str(in2);
  for (auto i : t2)for(auto j:i)cout << j << endl;
  return 0;
}

CodePudding user response:

I just eliminated the compile-break , but actual situation changes are depend on your opinion and condition , So you should replace correct change.

#include <fstream>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
using namespace std;
inline string stringToVecStr(const string input) {
  string result;
  for (int i = 1; i < input.length() - 1; i  ) {
    char currentChar = input[i];
    if (input[i] == '\\') {
      char nextChar = input[i   1];
      switch (nextChar) {
        case '\"':
          result.push_back('\"');
          break;
        case '/':
          result.push_back('/');
          break;
        case '\\':
          result.push_back('\\');
          break;
        case 'b':
          result.push_back('\b');
          break;
        case 'f':
          result.push_back('\f');
          break;
        case 'r':
          result.push_back('\r');
          break;
        case 'n':
          result.push_back('\n');
          break;
        case 't':
          result.push_back('\t');
          break;
        default:
          break;
      }
      i  ;
    } else {
      result.push_back(currentChar);
    }
  }
  return result;
}

const int32_t TREE_NODE_BOUNDNARY = INT_MIN   1;  // replace null

// note:Vec() is to hanlde `vector<int>` such as `[1,2,3,4,5]`
template <typename T>
std::vector<T> Vec(const std::string inputStr) {
  std::vector<T> ret;
  const std::string pattern = R"(([ |-]?\w*\.?[\w |#|(|)|\.]),?)";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    std::stringstream ss;
    std::string treeNull = match.str(1) == "null"
                               ? std::to_string(TREE_NODE_BOUNDNARY)
                               : match.str(1);
    ss << treeNull;
    T temp;
    ss >> temp;
    ret.push_back(temp);
    log = match.suffix();
  }
  if (ret.empty()) std::cout << "构造Vector失败" << std::endl;
  return ret;
}

template <typename T>
std::vector<std::vector<T>> Vec2(
    const std::string &inputStr) {  // change to refrence(prevent copy)
  std::vector<std::vector<T>> ret;
  const std::string pattern = R"((\[[^\[\]]*\]))";
  std::smatch match;
  std::string log = inputStr;
  while (regex_search(log, match, (std::regex)pattern)) {
    std::string vec = match.str(1);
    if (is_same_v<T, string>) {
      string temp = stringToVecStr(vec);
      ret.push_back(std::vector<T>(
          1, temp));  // changed -> std::vector init , but this code
                      // always add one string to vector if you want add
                      // to an item in outer vector , you should have an
                      // condition to add which one element?
    } else {
      ret.push_back(Vec<T>(vec));  // you checked type not be string , but input
                                   // argument in Vec(...) is string . why?
    }
    log = match.suffix();
  }

  if (ret.empty()) {
    std::cout << "Failed to construct Matrix" << std::endl;
  }
  return ret;
}

int main() {
  std::string in1 = "[\">>v\",\"v^<\",\"<><\"]";
  auto t1 = stringToVecStr(in1);
  for (auto i : t1) cout << i;
  cout << endl;

  std::string in2 = "[[\">>v\",\"v^<\",\"<><\"],[\">>v\",\"v^<\",\"<><\"]]";
  auto t2 = Vec2<string>(in2);
  for (auto const &i : t2)  // changed
    for (auto const &j : i) cout << j << " ";
  return 0;
}

  • Related