C++ 运算符的泛型重载<< for STL containers produces ambiguous overload error with strings

问题描述 投票:0回答:1

我的意思是编写

operator<<
的通用重载来打印 STL 容器。 我在下面整理了代码。 每当
operator<<
涉及
string
时,都会产生编译错误
ambiguous overload for 'operator<<'
,在 问题行 1 和 2 的示例中。

如何消除错误,而又不丢失通用重载,并且不必为带有字符串的容器的每种可能使用编写显式实例化? 也许从我的重载中排除字符串(我不知道这是否可能)。

#include <iostream>
#include <vector>
#include <set>
#include <list>
#include <map>
#include <tuple>
#include <string>

// Maximum number of printed values. After this, print "..."
#define MAX_PRINT_VALS 10

//=========================================================================
// Set of functions to dump STL containers

template <template <class...> class Container, class ...T>
std::ostream& operator<<(std::ostream& os, const Container<T...>& c)
{
    os << "[";

    size_t nvals = 0;
    for ( auto iter = c.begin() ; iter != c.end() ; iter++ ) {
        os << *iter;
        nvals++;
        if (iter != --c.end())
            os << ", ";
        if (nvals > MAX_PRINT_VALS) {
           os << "... (total of " << c.size() << " values)";
           break;
        }
    }

    os << "]";
    return os;
}

template<class Key, class T>
std::ostream& operator<<(std::ostream& os, const std::pair<Key, T>& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    //os << std::endl;
    return os;
}


using namespace std;


int main(int argc, char **argv) {

    //============================================================
    // Print vector
    const size_t nmax = 3;
    vector<double const*> vec_dp;
    for (size_t n = 0; n < nmax; n++) {
        vec_dp.push_back(new double(n+1.5));
    }
    cout << "Vector of indices vec_dp = " << vec_dp << endl;
    for (size_t n = 0; n < nmax; n++) {
        delete vec_dp[n];
    }

    vector<string> vec_s;
    for (size_t n = 0; n < nmax; n++) {
        vec_s.push_back("asa");
    }
    cout << "Vector of string vec_s = " << vec_s << endl;         // PROBLEM LINE 1

    //============================================================
    // Print set
    set<double> set_d;
    for (size_t n = 0; n < nmax; n++) {
        set_d.insert(n+1.3);
    }
    cout << "Set of double set_d = " << set_d << endl;

    //============================================================
    // Print list
    list<double> list_d;
    for (size_t n = 0; n < (nmax + 10); n++) {
        list_d.emplace_back(n+1.4);
    }
    cout << "List of double list_d = " << list_d << endl;

    //============================================================
    // Print map
    typedef pair<int, int> pair2_t;
    map<pair2_t::first_type, pair2_t::second_type> map_i_i;
    for (size_t n = 0; n < (nmax + 10); n++) {
        map_i_i.insert(pair2_t(n+1, n+2));
    }
    cout << "Map of (int, int) map_i_i = " << map_i_i << endl;

    typedef pair<int, string> pair1_t;
    map<pair1_t::first_type, pair1_t::second_type> map_i_s;
    for (size_t n = 0; n < (nmax + 10); n++) {
        map_i_s.insert(pair1_t(n+1, "one"));
    }
    cout << "Map of (int, string) map_i_s = " << map_i_s << endl;         // PROBLEM LINE 2


    return 0;
}

相关

  1. C++ 打印模板容器错误(错误:'operator<<') understanding?
  2. 的重载不明确)
  3. “运算符”的重载不明确<<’ in ‘std::cout <<
c++ string stl c++17 operator-overloading
1个回答
0
投票

如何消除错误,而又不丢失通用重载,并且不必为带有字符串的容器的每种可能使用编写显式实例化? 也许从我的过载中排除字符串

您可以将折叠表达式与

std::enable_if
结合使用来排除您自己的
std::string
重载,如下所示:

template <template <class... K> class Container, class ...T   >  
//added this to make use of SFINAE
std::enable_if_t<not (std::is_same<std::string, Container<T>>{} || ...),std::ostream&> 
                     operator<<(std::ostream& os, const Container<T...>& c)   
{                  
    os << "["; 

    size_t nvals = 0;
    for ( auto iter = c.begin() ; iter != c.end() ; iter++ ) {
        os << *iter;
        nvals++;
        if (iter != --c.end())
            os << ", ";
        if (nvals > MAX_PRINT_VALS) {
           os << "... (total of " << c.size() << " values)";
           break;
        }
    }

    os << "]";
    return os;
}
int main(int argc, char **argv) {

     //other code as before
     cout << "Vector of string vec_s = " << vec_s << endl; //works now    
} 

工作演示

© www.soinside.com 2019 - 2024. All rights reserved.