我怎样才能为一个概念重载一个函数?
How can I overload a function for a concept?
假设我有一个函数模板和各种“专门化”该模板的重载。由于重载在重载解析期间比模板版本更匹配,因此它们将始终获得优先级。
template <typename T>
void dispatch(T&& t) {
std::cout << "generic\n";
}
void dispatch(int) {
std::cout << "int\n";
}
dispatch(5); // will print "int\n"
dispatch(nullptr); // will print "generic\n";
现在我遇到了这样的情况,我有一个专门化可以用于一整套(不相关的)类型,但是满足概念的约束,例如:
template <std::floating_point T>
void dispatch(T t) {
if constexpr(std::is_same_v<T, float>) std::cout << "float\n";
else std::cout << "unknown\n";
}
不幸的是,这个重载与一般情况不相上下,所以像 dispatch(1.0f)
这样的调用是不明确的。当然,我可以通过为所有类型(我目前知道的)提供显式重载来解决这个问题,但是由于我的实际应用程序中的类型数量很大(而且客户可能会添加更多类型的这个概念)和代码这些类型中的每一种都非常相似(编译时已知的微小差异),这将是很多重复。
有没有办法为整个概念重载一个函数?
受约束的函数模板只有在具有 the same template-parameter-lists and function parameter types 时才能击败不受约束的函数模板。所以要么让通用的取一个值(这样两者都取 T
):
template <typename T>
void dispatch(T t) {
std::cout << "generic\n";
}
或者使浮点数成为转发引用(这样两者都采用T&&
):
template <typename T>
requires std::floating_point<std::remove_cvref_t<T>>
void dispatch(T&& t) {
if constexpr(std::is_same_v<T, float>) std::cout << "float\n";
else std::cout << "unknown\n";
}
假设我有一个函数模板和各种“专门化”该模板的重载。由于重载在重载解析期间比模板版本更匹配,因此它们将始终获得优先级。
template <typename T>
void dispatch(T&& t) {
std::cout << "generic\n";
}
void dispatch(int) {
std::cout << "int\n";
}
dispatch(5); // will print "int\n"
dispatch(nullptr); // will print "generic\n";
现在我遇到了这样的情况,我有一个专门化可以用于一整套(不相关的)类型,但是满足概念的约束,例如:
template <std::floating_point T>
void dispatch(T t) {
if constexpr(std::is_same_v<T, float>) std::cout << "float\n";
else std::cout << "unknown\n";
}
不幸的是,这个重载与一般情况不相上下,所以像 dispatch(1.0f)
这样的调用是不明确的。当然,我可以通过为所有类型(我目前知道的)提供显式重载来解决这个问题,但是由于我的实际应用程序中的类型数量很大(而且客户可能会添加更多类型的这个概念)和代码这些类型中的每一种都非常相似(编译时已知的微小差异),这将是很多重复。
有没有办法为整个概念重载一个函数?
受约束的函数模板只有在具有 the same template-parameter-lists and function parameter types 时才能击败不受约束的函数模板。所以要么让通用的取一个值(这样两者都取 T
):
template <typename T>
void dispatch(T t) {
std::cout << "generic\n";
}
或者使浮点数成为转发引用(这样两者都采用T&&
):
template <typename T>
requires std::floating_point<std::remove_cvref_t<T>>
void dispatch(T&& t) {
if constexpr(std::is_same_v<T, float>) std::cout << "float\n";
else std::cout << "unknown\n";
}