C++ 使用模板重载函数
我试图使用模板定义一个函数,我希望typename是int或anEnum(我定义的特定枚举)。我尝试了以下方法,但失败了:C++ 使用模板重载函数,c++,templates,overloading,C++,Templates,Overloading,我试图使用模板定义一个函数,我希望typename是int或anEnum(我定义的特定枚举)。我尝试了以下方法,但失败了: template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T> bool isFunction(const T &aVariable){} 模板//或 bool-isFunction(const-T&aVariable){} 我想做的是使用模板,而不是定
template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T>
bool isFunction(const T &aVariable){}
模板//或
bool-isFunction(const-T&aVariable){}
我想做的是使用模板,而不是定义两个重载函数。
我希望函数被称为以下函数,而程序员不必考虑类型
isFunction(aVariable) // and not isFunction<int> (aVariable) nor isFunction<anEnum> (aVariable)
isFunction(aVariable)//而不是isFunction(aVariable)或isFunction(aVariable)
基本上,我希望这个函数是int和aNum类型的模板。我已经找过了,但找不到答案。我会错过什么?谢谢,有几种方法可以实现这一点。所有这些都涉及使用标题。例如,您可以在函数体中对有问题的类型进行静态断言
或者,如果需要在其他重载中考虑这个函数,可以使用sFiAE技术。
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> {
}
模板
自动isFunction(常量和变量)
->std::如果启用,则启用{
}
如果类型不匹配,这将在调用之前从重载集中删除函数。但是,如果您不需要这种行为,静态断言确实允许出现对程序员更友好的错误消息。除了非C++20答案之外,如果您能够使用C++20及其功能,我建议您使用以下实现:
#包括
#包括
枚举类MyEnum{
A.
B
C
};
模板
概念integratorenum=std::与| | std::integral相同;
模板
布尔函数(常量和变量){
返回true;
}
int main(){
isFunction(MyEnum::A);
功能(3);
isFunction(“my_字符串”);//错误
返回0;
}
更新
根据他的评论,以下是一种更具可扩展性和可重用性的方法:
模板
概念一(std::is_same_v | | |……);
模板
布尔函数(常量和变量){
返回true;
}
这个解决方案怎么样?如果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;
}
#包括
茴香{
//
};
模板
布尔函数(常量和变量)
{
静态断言(定义为“无效专门化”);
布尔结果=假;
//把你的代码放在这里
返回结果;
}
我改进了答案。”如果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 << "int\n";
// 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_view\n";
return true;
}
int main()
{
isFunction(std::string_view("1L"));
isFunction(1);
//isFunction(1L); // will produce an error message from static_assert
}
模板
结构总是\u false:std::false\u类型{};
模板
布尔函数(常量和变量)
{
如果constexpr(std::is_same_v | | std::is_same_v)
{
std::cout如果它确实是一个枚举或int类型,为什么不同时编写这两个函数?为什么在这种情况下需要一个模板?其他类型如何?是否要为其他类型返回false
,还是不为其他类型实例化函数。@Frogato否,bool返回值与类型无关。@Klaus I'我已要求了解替代方案。根据当前的答案,我决定简单地定义这两个函数。如果存在其他签名(例如,假设的isFunction(std::string\u视图)
),则这对重载解析不起作用。'。签名仍将是有效的匹配项,但实例化会导致错误。您可以将无用的签名声明为已删除:bool isFunction(std::string_view)=delete;我指的是其他重载。在这种情况下,此无效签名可能最终是完全匹配的(例如,对于字符串文字),从而阻止重载。static_assert(false,…)
是格式不正确的NDR,甚至没有被使用。如果你幸运的话,你的编译器会像Clang一样立即告诉你,非常感谢你的评论,我犯了一个错误。修复了,对于要求类型为两个特定类型之一的特定情况,类似这样的方法可能会更好:模板概念一个=(std::is_same_v | | |…)
模板bool isFunction(T const&aVariable){
@RichardSmith我也用它更新了我的答案。我发现这更可重用和可扩展。谢谢
template <typename T>
struct always_false : std::false_type {};