c++ - 调用较少约束的功能等效函数
问题描述
考虑以下代码:
#include <iostream>
#include <type_traits>
struct A;
template<class T>
concept HasParent = std::is_convertible_v<typename T::parent*, A*>;
struct A{};
struct B : A { using parent = A; };
template<class T> int foo(T*) { return 1; }
template<HasParent T> int foo(T*)
{
// call the other one?
return 2;
}
int main()
{
B b;
std::cout << foo(&b) << std::endl; // displays 2
return 0;
}
是否可以从 调用通用foo<T>(T*)
函数foo<HasParent T>(T*)
?
(这是一个(功能性)示例,但我可以在 github 上链接完整代码)
解决方案
是否可以从 调用通用
foo<T>(T*)
函数foo<HasParent T>(T*)
?
为了做到这一点,您需要一些方法来区分这两个功能。
例如:
template <typename T> void foo(T);
template <typename T> requires true auto foo(T) -> int;
第二个显然比第一个更受限制T
,所以foo(42)
称为第二个。但是,您可以区分两者:
auto unconstrained = static_cast<void(*)(int)>(foo);
在这里,受约束的函数模板返回int
,因此它不是一个可行的候选者,我们得到了不受约束的模板。
在你的例子中,两者都 return int
,所以这个特殊的技巧不起作用。但关键是你需要一些方法来区分这两个模板。
更好的方法可能是:
template <typename T, std::monostate M = {}>
void foo(T);
template <typename T> requires true
void foo(T arg) {
foo<T, std::monostate{}>(arg); // calls the unconstrained one
}
在这里使用monostate
有点可爱,因为它实际上并没有改变模板实例化的数量(只有一个monostate
... )。foo(42)
调用第二个,后者调用第一个。演示。
但是最好只添加一个新函数并让函数模板的无约束和约束版本都调用该函数(从某种意义上说,它可以说比该monostate
方法更不神秘)。
推荐阅读
- swift - 防止在swift 5中粘贴到文本字段中
- c# - 如何为 sl5 目标框架构建 SDK 风格的项目?
- android - 如何在 react-native 的函数内部组件中使用变量?
- python - GluonCV ImportError:无法导入名称“is_np_array”
- python-3.x - 如果在单元格 A1 中找到字符串,则在 B1 单元格中替换 python pandas
- scala - Spark(scala):如何将 UDF 转换应用于嵌套数据中的数组列
- reactjs - React 类组件中的“Timer”类型上不存在 this.setinterval
- javascript - javascript中 Math.floor() 的第二个参数有什么用?
- javascript - 如何通过 shopify 页面视图触发 zap?
- ionic-framework - 希望将我的 ionic 4 项目与 pouchdb 连接起来。但不断收到错误“无法访问词法声明”