考虑以下代码:
#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*)
?
你需要some方法来区分这两个函数以实现此目的。
例如:
template <typename T> void foo(T);
template <typename T> requires true auto foo(T) -> int;
对于所有人来说,第二个显然比第一个受到更多限制T
, so foo(42)
呼叫第二个。但是你can区分两者:
auto unconstrained = static_cast<void(*)(int)>(foo);
这里,约束函数模板返回int
所以它不是一个可行的候选者,我们得到了不受约束的候选者。
在您的示例中,两者都返回int
,所以这个特殊的技巧不起作用。但关键是你需要some区分这两个模板的方法。
更好的方法可能是:
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
}
Using monostate
这有点可爱,因为它实际上并没有改变模板实例化的数量(只有一个monostate
... ). foo(42)
调用第二个,第二个调用第一个。Demo.
但最好只添加一个新函数,并让函数模板的无约束和约束版本都调用该函数(从某种意义上说,它可能比monostate
方法)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)