Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用模板重载函数_C++_Templates_Overloading - Fatal编程技术网

C++ 使用模板重载函数

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){} 我想做的是使用模板,而不是定

我试图使用模板定义一个函数,我希望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){}
我想做的是使用模板,而不是定义两个重载函数。 我希望函数被称为以下函数,而程序员不必考虑类型

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 {};