[英]Is there a way to find out if a class has an overloaded operator?
我正在編寫一個模板類,在其中需要一種將元素類stdout
到stdout
。 但是我在編寫它時遇到了問題-如果在我的元素類中未定義cout <<
或operator const char*()
怎么辦?
有沒有一種方法可以找出可能引發異常而不會得到編譯錯誤的方法?
如果運算符沒有重載,則您的程序將無法編譯。 這是一個編譯時錯誤,無法將其延遲到運行時。
解決方法是不使用運算符,而使用函數指針。 如果不支持該操作,則可以將功能指針設置為0,您可以在運行時檢測到該指針。
class A {
public:
int q; // some data
typedef std::function<void(std::ostream& os, const A&)> PrinterFunc;
PrinterFunc func;
friend std::ostream& operator<<(std::ostream& os, const A& a) {
if(!a.func) {
throw "Not supported";
}
func(os,a);
return os;
}
};
A a;
a.func = [](std::ostream& os, const A& a) { os << "hello " << a.q; }
std::cout << a << std::endl; // will print
A b;
std::cout << b << std::endl; // will throw
本示例使用C ++ 11和<functional>
。 對於C ++ 03,您將必須使用“常規”函數指針。
您可以使用一些SFINAE來測試是否存在(格式化的)輸出運算符:
#include <iostream>
// HasFormattedOutput
// ============================================================================
namespace HasFormattedOutput {
namespace Detail
{
struct Failure{};
}
template<typename OutputStream, typename T>
Detail::Failure operator << (OutputStream&, const T&);
template<typename OutputStream, typename T>
struct Result : std::integral_constant<
bool,
! std::is_same<
decltype(std::declval<OutputStream&>() << std::declval<T>()),
Detail::Failure
>::value
> {};
} // namespace HasFormattedOutput
template <typename T, typename OutputStream = std::ostream>
struct has_formatted_output : std::conditional<
HasFormattedOutput::Result<OutputStream, T>::value,
std::true_type,
std::false_type>::type
{};
// Test
// ============================================================================
struct X {};
int main() {
std::cout.setf(std::ios_base::boolalpha);
std::cout << has_formatted_output<const char*>() << '\n';
std::cout << has_formatted_output<X>() << '\n';
}
(C ++ 11)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.