gpt4 book ai didi

c++ - 用于确定类是否输出可流式意外输出的元程序

转载 作者:行者123 更新时间:2023-11-30 01:54:56 34 4
gpt4 key购买 nike

我以为我已经想出了如何制作一个模板来确定一个类/结构是否可以流式传输到 ostream(例如,“可打印”)但是我写的模板中有一个缺陷来做到这一点.希望了解我哪里出错了,以及让模板按照我期望/想要的方式工作的任何解决方案。

所以我的问题是

  1. 我是否遗漏了一些非常基本的东西,或者这比模板考虑的更复杂?
  2. 我没有查看模板与右值引用的交互:它们是否也会对模板造成问题?

完整代码 here .


这是模板

template<typename T, typename U>
class isOutputStreamable {
private:
template<typename V, typename W> static decltype(operator<<(std::declval<V>(), std::declval<W>()), std::true_type()) check_(int);
template<typename, typename> static std::false_type check_(...);
public:
static const bool value = decltype(check_<T, U>(0))::value;
};

我正在测试的类

struct Empty {
};

struct Streamer {
};

std::ostream& operator<<(std::ostream& ostream, const Streamer&) {
return ostream << "Streamer";
}

按我期望的方式工作的 static_asserts

// Streamer should show as ostreamable
static_assert( isOutputStreamable< std::ostream&, const Streamer& >::value, "Goodness" );
static_assert( isOutputStreamable< std::ostream&, const Streamer >::value, "Goodness" );
static_assert( isOutputStreamable< std::ostream&, Streamer& >::value, "Goodness" );
static_assert( isOutputStreamable< std::ostream&, Streamer >::value, "Goodness" );

// isOutputStreamable works with a value ostream for Streamer
static_assert( isOutputStreamable< std::ostream, const Streamer& >::value, "Goodness" );
static_assert( isOutputStreamable< std::ostream, const Streamer >::value, "Goodness" );
static_assert( isOutputStreamable< std::ostream, Streamer& >::value, "Goodness" );
static_assert( isOutputStreamable< std::ostream, Streamer >::value, "Goodness" );

// Empty should not show as ostreamable
static_assert( !isOutputStreamable< std::ostream&, const Empty& >::value, "Goodness" );
static_assert( !isOutputStreamable< std::ostream&, const Empty >::value, "Goodness" );
static_assert( !isOutputStreamable< std::ostream&, Empty& >::value, "Goodness" );
static_assert( !isOutputStreamable< std::ostream&, Empty >::value, "Goodness" );

// With a const ostream nothing should show as ostreamable
static_assert( !isOutputStreamable< const std::ostream&, const Streamer& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, const Streamer >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, Streamer& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, Streamer >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , const Streamer& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , const Streamer >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , Streamer& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , Streamer >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, const Empty& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, const Empty >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, Empty& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream&, Empty >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , const Empty& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , const Empty >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , Empty& >::value, "Goodness" );
static_assert( !isOutputStreamable< const std::ostream , Empty >::value, "Goodness" );

然后是没有的static_asserts

// Unexpected results: I wanted these to all fail
static_assert( isOutputStreamable< std::ostream, const Empty& >::value, "Badness" );
static_assert( isOutputStreamable< std::ostream, const Empty >::value, "Badness" );
static_assert( isOutputStreamable< std::ostream, Empty& >::value, "Badness" );
static_assert( isOutputStreamable< std::ostream, Empty >::value, "Badness" );

在此先感谢您的帮助。


更新

@Casey:感谢您的帮助。我非常确信模板有问题我想我完全错过了它可能实际上匹配正确的事实。至于你关于如何围绕这个切换模板的建议,这当然是很容易做到的;但是,我很好奇是否没有其他解决方案适合我接下来要说的内容。

该模板实际上是根据我希望的通用宏生成的,用于创建这些类型的检查器模板

   #define BINARY_FUNCTION_EXISTS_(FUNCTION_NAME_, CHECK_NAME_) \
template<typename T, typename U> class CHECK_NAME_ {\
private:\
template<typename V, typename W> static decltype(FUNCTION_NAME_(std::declval<V>(), std::declval<W>()), std::true_type()) check_(int);\
template<typename, typename> static std::false_type check_(...);\
public:\
static const bool value = decltype(check_<T, U>(0))::value;\
};

是否因为匹配模板(在我的情况下不受欢迎),这个支持 ostream 的模板需要是一个特例?我认为答案是肯定的,但我已经对此感到困惑,问问也无妨。再次感谢。

最佳答案

1.标准库定义了一个不受约束的模板函数,它在左值流插入方面为所有类型提供右值流插入:

C++11 §27.7.3.9 Rvalue stream insertion [ostream.rvalue]

template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);

1 Effects: os << x

2 Returns: os

这显然打破了您对右值 ostream 的检测。

2。自 decltype(std::declval<T>())decltype(std::declval<T&&>())都是T&& ,它将与右值引用一起正常工作; IsOutputStreamable<T, U&&>::value将等于 IsOutputStreamable<T, U>::value .

关于c++ - 用于确定类是否输出可流式意外输出的元程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21295365/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com