C++ 根据是否存在某个函数启用模板

C++ 根据是否存在某个函数启用模板,c++,templates,operator-overloading,c++14,sfinae,C++,Templates,Operator Overloading,C++14,Sfinae,我想设计一个模板,自动提供操作符编辑: 您的代码没有陷阱,对此表示抱歉。但这个答案使您能够编写更像C++20概念的代码: template <class T> auto& operator << (std::ostream &out, const printable_t<T> &t) { t.print_to(out); return out; } 您可以尝试向该代码添加C++14支持。这不会太难。概念\u T必须更改

我想设计一个模板,自动提供
操作符编辑:

您的代码没有陷阱,对此表示抱歉。但这个答案使您能够编写更像
C++20
概念的代码:

template <class T>
auto& operator << (std::ostream &out, const printable_t<T> &t)
{
    t.print_to(out);
    return out;
}

您可以尝试向该代码添加
C++14
支持。这不会太难。
概念\u T
必须更改为
constexpr const static bool
以调整为
C++14

在我看来,您在
运算符中的应用似乎是正确的,但。。。你为什么说朱塞佩的SFINAE实施是错误的?在我看来,这似乎是正确的。@max66您是对的……很抱歉有误导性的说法。这个版本非常简洁,适合只使用一两次的
概念。@Glovanni Mascellani实际上您是在试图检测
概念
。。。和[Constraints and concepts(TS)]()将值得一看。对于
C++17
C++14
概念
,请看一下我的答案。为什么这里需要
typename=decltype
,我试图删除它,但没有做任何更改?
template <class T>
auto& operator << (std::ostream &out, const printable_t<T> &t)
{
    t.print_to(out);
    return out;
}
#include <type_traits>
#include <utility>
#include <ostream>

// For support for C++17 is not complete in many compiler, I also define void_t
template <class...> using void_t = void;

namespace impl {
template <class Default, class AlwaysVoid, template <class...> class Op, class ...Args>
struct detector: private std::false_type
{
    using std::false_type::value;
    using type = Default; 
};   
template <class Default, template <class...> class Op, class ...Args>
struct detector<Default, void_t<Op<Args...>>, Op, Args...>: private std::true_type
{
    using std::true_type::value;
    using type = Op<Args...>;
}; 
} // namespace impl

struct nonsuch {};

#define CONCEPT_T constexpr const static inline bool
template <template<class...> class Op, class ...Args>
CONCEPT_T is_detected_v = impl::detector<nonsuch, void, Op, Args...>::value;

// Detect whether print_to exists.    
template <class T>
using print_to_ret_t = decltype( std::declval<T>().print_to( std::declval<std::ostream&>() ) );

template <class T>
CONCEPT_T has_func_print_to_v = is_detected_v<print_to_ret_t, T>;

template <class T, std::enable_if_t< has_func_print_to_v<T> >>
using printable_t = T;

#undef  CONCEPT_T
template <typename T>
auto operator<< (std::ostream & s, T const & t)
   -> decltype( t.print_to(s), s )
 {
   t.print_to(s);

   return s;
 }