代码之家  ›  专栏  ›  技术社区  ›  463035818_is_not_an_ai

错误:尝试检测std::cout<<t时函数强制转换为数组类型;是有效的

  •  -1
  • 463035818_is_not_an_ai  · 技术社区  · 7 年前

    由对此的评论触发 answer 我想写(在C++ 11)中

    template <typename T>
    struct has_out_op { static const bool value = ???; }
    

    解除/启用成员功能取决于 std::cout << t; T t . 我走了这么远。。。

    #include <iostream>
    
    struct can_convert_to_base{}; // but does not when there is a better match
    struct base {base(can_convert_to_base);};
    
    template <typename T> 
    auto test(const T& t,can_convert_to_base) 
    -> decltype( std::cout << t);
    
    template <typename T> 
    std::false_type test(const T& t,base);
    
    template <typename T>
    struct has_out_op {
        static const bool value = 
            !std::is_same<std::false_type,
                          decltype( test(T(),can_convert_to_base()) )
                          >::value;
    };
    
    struct A{};
    
    int main() {
        std::cout << has_out_op<int>::value;   // prints 1
        std::cout << has_out_op<A>::value;     // prints 0
    }
    

    struct B {
        template <typename T>
        typename std::enable_if<has_out_op<T>::value,B&>::type operator<<(const T& t)  {
            std::cout << t;
            return *this;
        }
    };
    int main() {
        B b;
        b << "1";
    }
    

    我得到了错误

    prog.cc: In instantiation of 'const bool has_out_op<char [2]>::value':
    prog.cc:25:60:   required by substitution of 'template<class T> typename std::enable_if<has_out_op<T>::value, B&>::type B::operator<<(const T&) [with T = char [2]]'
    prog.cc:31:14:   required from here
    prog.cc:17:67: error: functional cast to array type 'char [2]'
                               decltype( test(T(),can_convert_to_base()) )
                                                                       ^
    prog.cc: In function 'int main()':
    prog.cc:31:11: error: no match for 'operator<<' (operand types are 'B' and 'const char [2]')
             b << "1";
               ^
    

    后来我意识到 has_out_op 要求 T test 如果 标准::cout<&书信电报;t; 是有效的,但仅凭类型我不知道如何正确实现 .

    如何检测是否有匹配的过载 标准::cout<&书信电报;t; decltype(t) ?

    请注意,我已经知道如何解除/启用 B::operator<< 是的,但是出于勇气我还在努力 已经用完了 正确的。

    1 回复  |  直到 7 年前
        1
  •  1
  •   bolov    7 年前

    std::declval<T>() 为了救援:

    T 引用类型,使使用 成员函数 decltype 表达 不需要去 .

    注意,因为declval没有定义,所以只能是 在未评估的上下文中使用;我

     ...
     decltype( test(std::declval<T>(),can_convert_to_base()) )
     ...
    

    既然我们已经到了,你的解决方案就太复杂了。我会这样做:

    struct B {
        template <typename T, class = decltype(std::cout << std::declval<T>())>
        B& operator<<(const T& t)
        {
            std::cout << t;
            return *this;
        }
    };
    

    不过,如果有更简单的解决方案,我会很感兴趣

    template <typename T>
    struct has_out_op_impl
    {
        template <class U, class = decltype(std::cout << std::declval<U>())>
        static auto foo(U) -> std::true_type;
    
        static auto foo(...) -> std::false_type;
    
        using Type = decltype(foo(std::declval<T>()));
    };
    
    template <class T>
    struct has_out_op : has_out_op_impl<T>::Type
    {};
    
    struct A{};
    
    int t1()
    {
        static_assert(has_out_op<int>::value == true, "");
        static_assert(has_out_op<A>::value == false, "");
    }