考虑以下代码,其中一个函子
derived
,继承自两个基类
base1
和
base2
每个都提供不同的重载:
// Preamble
#include <iostream>
#include <functional>
#include <type_traits>
// Base 1
struct base1 {
void operator()(int) const {
std::cout << "void base1::operator()(int) const\n";
}
void operator()(double) const {
std::cout << "void base1::operator()(double) const\n";
}
template <class Arg, class... Args>
void operator()(const Arg&, Args&&...) const {
std::cout << "void base1::operator()(const Arg&, Args&&...) const\n";
}
};
// Base 2
struct base2 {
void operator()(int) {
std::cout << "void base2::operator()(int)\n";
}
void operator()(double) {
std::cout << "void base2::operator()(double)\n";
}
};
// Derived
struct derived: base1, base2 {
using base1::operator();
using base2::operator();
void operator()(char) {
std::cout << "void derived::operator()(char)\n";
}
};
// Call
template <class F, class... Args>
void call(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
// Main
int main(int argc, char* argv[]) {
const derived d1;
derived d2;
derived d3;
call(d1, 1); // void base1::operator()(int) const
call(d2, 1); // void base2::operator()(int)
call(d1, 1, 2); // void base1::operator()(const Arg&, Args&&...) const
call(d2, 1, 2); // void base1::operator()(const Arg&, Args&&...) const
call(d3, 'a'); // void derived::operator()(char)
return 0;
}
结果输出为:
void base1::operator()(int) const
void base2::operator()(int)
void base1::operator()(const Arg&, Args&&...) const
void base1::operator()(const Arg&, Args&&...) const
void derived::operator()(char)
这说明根据参数,所选重载可以来自
基准1
,
二进制数字系统
或
派生的
.
我的问题是
:是否可以在编译时通过创建一个类型特征来检测哪个类提供了所选的重载来执行相同的操作?
其形式如下:
template <
class Base1, // Possibly cv-ref qualified base1
class Base2, // Possibly cv-ref qualified base2
class Derived, // Possibly cv-ref qualified derived
class... Args // Possibly cv-ref qualified args
>
struct overload_origin {
using base1 = std::decay_t<Base1>;
using base2 = std::decay_t<Base2>;
using derived = std::decay_t<Derived>;
using type = /* base1, base2, or derived * /
};
以及在
call
前面示例代码中的函数
overload_origin::type
参考
基准1
,
二进制数字系统
,
基准1
,
基准1
,
派生的
对于示例代码中所示的五个调用。
如何使用模板元编程实现这样的事情?