c++ - 如何在编译期间输出诊断消息以判断调用了哪个重载函数
问题描述
例如,我有重载函数f()
,它们被定义为
struct Test {
int i = 1;
Test(double d) : i (d){}
};
struct MyClass {
int f(double d) {
cout << "parent\n";
return d + 3 ; }
};
struct Child : public MyClass {
using MyClass::f; // if we comment out this line, the output will be different
double f(Test t) {
cout << "child\n";
return t.i * 9;
}
};
int main() {
Child c;
std:: cout << c.f(1.0) << std::endl;
}
Child 类中的函数f
重载了父类中的函数。我们如何在编译期间生成诊断信息,以便我们知道编译器选择了哪个函数c.f(1.0)
?
请注意,如果我删除 line using MyClass:f;
,输出会有所不同,但编译不会出错。
更新:
根据@PW 的回答,有两种方法可以修改现有类以使用模板实例化来输出静态断言,
template <typename T>
struct ConditionalFalse {
static constexpr bool value = false;
};
struct Test {
int i = 1;
Test(double d) : i (d){}
};
struct MyClass {
template<typename T>
int f(double i) {
static_assert(ConditionalFalse<T>::value, "Parent");
return i + 3 ; }
};
struct Child : public MyClass {
using MyClass::f;
template<typename T>
double f(Test t) {
static_assert(ConditionalFalse<T>::value, "Child");
return t.i * 9;
}
};
template<typename T>
struct MyClassT {
int f(double i) {
static_assert(ConditionalFalse<T>::value, "ParentT");
return i + 3 ; }
};
template<typename T>
struct ChildT : public MyClassT<T> {
using MyClassT<T>::f;
double f(Test t) {
static_assert(ConditionalFalse<T>::value, "ChildT");
return t.i * 9;
}
};
int main() {
Child c;
std:: cout << c.f<int>(1.0) << std::endl;
ChildT<int> ct;
std:: cout << ct.f(1.0) << std::endl;
}
我仍然想知道这是否可以without
将类或成员函数修改为模板?
解决方案
一个简单static_assert(false_condition, "...")
的总是会在编译时失败。因此,您需要在编译时发生的事情,并且仍然依赖于其他事情。如果您的MyClass
和Child
是模板,您可以这样做。
您还需要一个依赖表达式,因此您可以使用辅助结构来获取与类型相关的内容。
现在您的代码将如下所示:
#include<iostream>
template <typename T>
struct ConditionalFalse { static constexpr bool value = false; };
struct Test {
int i = 1;
Test(double d) : i (d){}
};
template <typename T>
struct MyClass {
int f(double d) {
static_assert(ConditionalFalse<T>::value, "The Parent function is called\n");
return d + 3 ; }
};
template <typename T>
struct Child : public MyClass<T> {
using MyClass<T>::f; // if we comment out this line, the output will be different
double f(Test t) {
static_assert(ConditionalFalse<T>::value, "The Child function is called\n");
return t.i * 9;
}
};
int main() {
Child<int> c; //The template parameter doesn't matter
std::cout << c.f(1.0) << std::endl;
}
根据是否using MyClass<T>::f;
被评论,你会得到不同的断言。
如果没有评论,你会得到:
error: static assertion failed: The Parent function is called
static_assert(ConditionalFalse<T>::value, "The Parent function is called\n");
^~~~~~~~~~~~~~~~~~~
如果它被评论,你会得到:
<source>:22:19: error: static assertion failed: The Child function is called
static_assert(ConditionalFalse<T>::value, "The Child function is called\n");
^~~~~~~~~~~~~~~~~~~
你可以在这里看到它。
推荐阅读
- reactjs - npm start on new create-react-app build 返回 ELIFECYCLE 错误
- forms - 如何在 Form 中间使用 Flutter CircularProgressIndicator()?
- javascript - 如何使用 javascript 加载数据
- javascript - 如何使用 cookie 进行重定向
- ios - AVSpeechSynthesizer 冻结 iOS 应用几秒钟
- angular - EventEmitter 不发出值
- php - 如何给用户无限的浏览量
- android - 支持库冲突并在android中给出dex合并问题
- python-2.7 - 客户地址字段为空时如何禁止打印发票
- javascript - 用 startdate 和 endate 列表填充 fullcalender