是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
下面的问题如何检测类型是否可以流式传输到std :: ostream?我写了一个trait类,说明某些类型是否可以流式传输到IO流.直到现在我发现了一个问题,这个特性似乎运作良好.
我在使用LLVM的项目中使用代码,我正在使用他们的StringRef类(它与提议的std :: string_view类似).这是该类的Doxygen doc的链接,如果需要,您可以从中找到它的声明头文件.由于LLVM不提供运算符<<将StringRef对象流式传输到std流(它们使用自定义轻量级流类),因此我写了一个.
但是,当我使用特征时,如果我的自定义运算符<< 在特征之后被声明(这是因为我在一个标题中具有特征而操作符在另一个标题中的函数),则它不起作用.我曾经认为模板实例化中的查找是从实例化点的角度来看的,所以我认为它应该可行.实际上,正如你在下面看到的那样,使用另一个类及其自定义运算符<<,在特征之后声明,一切都按预期工作(这就是为什么我现在才发现这个问题),所以我无法弄清楚StringRef的原因特别.
这是完整的例子:
#include <iostream>
#include "llvm/ADT/StringRef.h"
// Trait class exactly from the cited question's accepted answer
template<typename T>
class is_streamable
{
template<typename SS, typename TT>
static auto test(int)
-> decltype(std::declval<SS&>() << std::declval<TT>(),
std::true_type());
template<typename, typename>
static auto test(...) -> std::false_type;
public:
static const bool value = decltype(test<std::ostream,T>(0))::value;
};
// Custom stream operator for StringRef, declared after the trait
inline std::ostream &operator<<(std::ostream &s, llvm::StringRef const&str) {
return …Run Code Online (Sandbox Code Playgroud) 最近我遇到了讨论is_streamable类型特征的问题.所以我决定实现我自己的版本并提出下一个解决方案来检查是否可以读取类型std::istream:
template<typename, typename = void>
struct is_readable_from_stream_impl
: std::false_type {};
template<typename T>
struct is_readable_from_stream_impl<T,
std::void_t<decltype(std::declval<std::istream&>() >> std::declval<T>())>>
: std::true_type {};
template<typename T>
struct is_readable_from_stream :
is_readable_from_stream_impl<T> {};
template<typename T>
inline constexpr auto is_readable_from_stream_v = is_readable_from_stream<T>::value;
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我添加了一个重载的自定义结构operator>>:
struct readable {};
std::istream& operator>>(std::istream& is, readable&)
{
return is;
}
Run Code Online (Sandbox Code Playgroud)
并测试了类型特征:
static_assert(is_readable_from_stream_v<readable&>);
static_assert(!is_readable_from_stream_v<readable>);
Run Code Online (Sandbox Code Playgroud)
该检查用均通过gcc 8.2和clang 6.0.0,但MSVC 拒绝第二个断言.
我想知道我的实现(或测试)是否不正确或者是另一个问题MSVC.