C++ print template container error (error: ambiguous overload for 'operator<<') understanding?

前端 未结 4 553
别跟我提以往
别跟我提以往 2021-01-22 18:35

I want to write template function which can print container like std::vector, std::list.

Below is my function, just overload <<.

4条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-22 18:52

    @miradham explained the issue very well.

    but this a more generic solution using SFINAE to make the overload considered only for types on which the range-based for loop can be used, what ever their template arguments can be.

    type coming form std::basic_string were ignored to prevent ambiguity with the standard operator << to display strings

    c-style array will not be displayed using this overload even though they could because they are decayed to pointers and displayed with the standard operator <<

    #include 
    #include 
    #include 
    #include 
    #include 
    
    template typename From, typename T>
    struct is_from : std::false_type {};
    
    template typename From, typename ... Ts>
    struct is_from > : std::true_type {};
    
    template 
    using void_t = void;
    
    template 
    struct is_input_iterator : std::false_type { };
    
    template 
    struct is_input_iterator()),
               decltype(*std::declval()),
               decltype(std::declval() == std::declval())>>
        : std::true_type { };
    
    template()))>::value &&
                            is_input_iterator()))>::value &&
                            !is_from::value, int>::type = 0>
    std::ostream& operator<<(std::ostream& out, const Container& c){
        for(const auto& item:c){
            out << item << " ";
        }
        return out;
    }
    
    int main(){
    
        std::array arr{0, 1, 2, 3, 4, 5};
        std::vector vec{5, 9, 1, 4, 6};
    
        std::cout << vec << std::endl;
        std::cout << arr << std::endl;
        std::cout << std::string("test") << std::endl;
        return 0;
    }
    

提交回复
热议问题