基于类型的任意属性的函数重载不起作用 [英] Function Overloading Based on Arbitrary Properties of Types doesn't work

查看:48
本文介绍了基于类型的任意属性的函数重载不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的示例中,我需要提取一些值.我有一个可以处理内置类型的高效提取器,以及一个可以处理所有内容的低效模板.要在这些之间进行选择,我想使用基于类型的任意属性的函数重载.这是我的代码:

In the example below, I need to extract some values. I have an efficient extractor, which can work with builtin types, and an inefficient template that can work with everything. To choose between these, I want to use Function Overloading Based on Arbitrary Properties of Types. Here is my code:

#include <string>
#include <iostream>

class extractor
{
public:
    static void extract(const bool& val) { std::cout << "Specialized extractor called" << std::endl; }
    static void extract(const double& val) { std::cout << "Specialized extractor called" << std::endl; }
};

template <typename T>
void extract_generic(const T& value) { std::cout << "Generic extractor called" << std::endl; }


template <typename T> struct is_extractor_native { static const bool val = false; };
template<> struct is_extractor_native<bool> {static const bool val = true; };
template<> struct is_extractor_native<double>  {static const bool val = true; };


template <bool B, class T = void>
struct enable_if {
    typedef T type;
};

template <class T>
struct enable_if<false, T> {};

template <typename T>
struct extract_caller
{

    //line 32 below
    static void extract(const T& val, typename enable_if<is_extractor_native<T>::val>::type * = 0)
    {
            extractor::extract(val);
    }

    //line 37 below
    static void extract(const T& val, typename enable_if<!is_extractor_native<T>::val>::type * = 0)
    {
            extract_generic(val);
    }
};



int main(void)
{
    std::string string_value("hello");
    double double_value(.123);

    std::cout << "native extractor for std::string: " << (int)is_extractor_native<std::string>::val << std::endl;
    std::cout << "native extractor for double:      " << (int)is_extractor_native<double>::val << std::endl;

    extract_caller<std::string>::extract(string_value);
    extract_caller<double>::extract(double_value);

    return 0;
}    

在我编译时,编译器会抱怨:

When I build the compiler complains:

g++     main.cpp   -o main
main.cpp: In instantiation of ‘extract_caller<std::basic_string<char> >’:
main.cpp:50:29:   instantiated from here
main.cpp:32:14: error: no type named ‘type’ in ‘struct enable_if<false, void>’
main.cpp: In instantiation of ‘extract_caller<double>’:
main.cpp:51:24:   instantiated from here
main.cpp:37:14: error: no type named ‘type’ in ‘struct enable_if<false, void>’
make: *** [main] Error 1

注释掉提取物并仅打印特征时,我得到正确的结果:

When comment out the extraction and have only the traits printed, I get correct results:

./main
native extractor for std::string: 0
native extractor for double:      1

在错误列表中,您可以看到,对于double,编译器在第32行传递了原型,转到37,并显示错误.问题是,为什么在这里不应用SFINAE原理?

On the error listing you can see that for double the compiler passes the prototype on line 32, goes to 37 and prints error. The question is, why the SFINAE principle is not applied here?

推荐答案

SFINAE仅在声明部分中发生某些错误(如您所遇到的错误)时起作用.在您的情况下,它们以定义的形式发生.对于struct extract_caller,必须重写代码,以便在声明中使用enable_if.

SFINAE only works when certain errors (like the ones you have) happen in declaration part. In your case they happen in definition. You have to rewrite your code so that enable_if is used in declaration, in your case of struct extract_caller.

这篇关于基于类型的任意属性的函数重载不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆