有没有办法找出一个类是否有重载运算符
Is there a way to find out if a class has an overloaded operator?
>我正在编写一个模板类,我需要一种方法将元素类打印到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)
相关文章:
- 此代码是否违反一个定义规则
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 是否可以同时声明一个类成员的常量/非常量?
- C++-字符串是否包含一个带有简单循环的单词
- 检查注册表项是否链接到(或副本)另一个注册表项
- 在C++行尾写一个分号或多个分号是否会改变任何内容
- 一元*运算符的操作数是否期望一个 prvalue
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 检查 2D 网格的某个元素是否与另一个元素共享对角线、水平线或垂直线
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 是否可以创建一个从不同类调用函数的线程?
- 这些场景中的任何一个是否会造成内存泄漏
- 在一个结构中,使用一个数组字段访问另一个是否合法
- C++检查前 5 个或接下来的 5 个元素中的任何一个是否等于值