使用模板重载函数
Overloading a function using templates
我正在尝试使用模板定义一个函数,并且我希望类型名称是int或anEnum(我定义的特定枚举(。我尝试了以下操作,但失败了:
template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T>
bool isFunction(const T &aVariable){}
我想做的是使用模板,而不是定义两个重载函数。我更喜欢如下调用函数,而程序员不必考虑类型
isFunction(aVariable) // and not isFunction<int> (aVariable) nor isFunction<anEnum> (aVariable)
基本上,我希望这个函数是为int和aNum类型模板化的。我已经找过了,但找不到答案。我可能缺少什么?谢谢你,
除了非C++20答案之外,如果您能够使用C++20及其concepts
功能,我建议您实现以下功能:
#include <iostream>
#include <concepts>
enum class MyEnum {
A,
B,
C
};
template <typename T>
concept IntegralOrEnum = std::same_as<MyEnum, T> || std::integral<T>;
template <IntegralOrEnum T>
bool isFunction(T const& aVariable) {
return true;
}
int main() {
isFunction(MyEnum::A);
isFunction(3);
isFunction("my_string"); // error
return 0;
}
演示
更新
根据@RichardSmith的评论,这里有一种更可扩展和可重复使用的方法:
template <typename T, typename ...U>
concept one_of = (std::is_same_v<T, U> || ...);
template <one_of<int, MyEnum> T>
bool isFunction(T const& aVariable) {
return true;
}
有几种方法可以实现这一点。所有这些都涉及使用type_traits
报头。例如,您可以在函数体中对有问题的类型进行静态断言。
或者,如果您需要在其他重载中考虑此函数,可以使用SFINAE技术。
template<typename T>
auto isFunction(const T &aVariable)
-> std::enable_if_t<std::is_same<T, int>::value || std::is_same<T,anEnum>::value, bool> {
}
如果类型不匹配,这将在调用重载集之前将该函数从重载集中删除。但是,如果您不需要这种行为,那么静态断言确实可以提供一个对程序员更友好的错误消息。
这个解决方案怎么样?如果类型T满足您的要求,则会编译带有该函数的代码。否则,静态断言失败。
#include <type_traits>
enum anEnum {
//
};
template <typename T, bool defined = std::is_same<T, int>::value ||
std::is_same<T, anEnum>::value>
bool isFunction(const T& aVariable)
{
static_assert(defined, "Invalid specialization");
bool result = false;
// Put your code here
return result;
}
我改进了https://stackoverflow.com/a/60271100/12894563回答。"如果constexpr在这种情况下可以提供帮助:
template <typename T>
struct always_false : std::false_type {};
template <typename T>
bool isFunction(const T& aVariable)
{
if constexpr(std::is_same_v<T, int> || std::is_same_v<T, anEnum>)
{
std::cout << "intn";
// put your code here
return true;
}
else
{
static_assert(always_false<T>::value, "You should declare non-template function or write if constexpr branch for your type");
return false;
}
}
bool isFunction(std::string_view)
{
std::cout << "std::string_viewn";
return true;
}
int main()
{
isFunction(std::string_view("1L"));
isFunction(1);
//isFunction(1L); // will produce an error message from static_assert
}
isFunction(1L(将失败,因为没有重载函数或"if constexpr"分支。
更新:修复了遗漏的
template <typename T>
struct always_false : std::false_type {};
https://godbolt.org/z/eh4pVn
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 可以打印矢量和矢量中的矢量的非重载C++函数
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 使用模板重载函数
- C++线程中,没有重载函数接受 X 参数
- std::vector 没有重载函数的实例与参数列表匹配
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- 对重载函数find_first_not_of的不明确调用
- 如何从重载解析中删除重载函数?
- CUDA:重载函数"isnan"的多个实例
- C++派生类重载函数(带有 std::function 参数)不可见
- 避免在人为的重载函数调用中拼写出类型
- C++:如何为多个重载函数保留通用代码路径?
- 什么时候可以使用常量装饰调用我的重载函数?
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- std::调用,未找到匹配的重载函数
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 为什么使用不匹配的参数调用重载函数仍然有效
- 如何通过签名作为模板参数来解决重载函数?