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_C++11_C++14 - Fatal编程技术网

C++ 通过合成实现函子重载

C++ 通过合成实现函子重载,c++,templates,c++11,c++14,C++,Templates,C++11,C++14,给定一些现有的函子: struct incr { int operator()(int x) const { return x + 1; } }; struct rep_str { std::string operator()(const std::string& s) const { return s + s; } }; 我想知道是否有可能实现这样的目标: auto f = overload<incr, rep_str>(); f(1);

给定一些现有的函子:

struct incr {
    int operator()(int x) const { return x + 1; }
};

struct rep_str {
    std::string operator()(const std::string& s) const { return s + s; }
};
我想知道是否有可能实现这样的目标:

auto f = overload<incr, rep_str>();
f(1);        // returns 2
f("hello");  // returns "hellohello"
auto f=重载();
f(1);//返回2
f(“你好”);//返回“hellohello”
多个重载可能如下所示:

auto f = overload<fa, fb, fc, ...>();
// or...
auto g = overload<fa, overload<fb, overload<fc, ...>>>();
auto f=重载();
//或者。。。
自动g=过载();
我在想也许可以将SFINAE与
std::result\u of_t
或类似的东西一起使用,但还没有弄清楚如何使用。

您不需要太花哨的东西:只需从所有参数继承,并使用using声明从基类引入
操作符()
。但是,在可变的情况下,在using声明中不能有包扩展,因此必须使用递归方法,如下所示:

template <class... Ts>
struct overload {}; // only used for empty pack

template <class T>
struct overload<T> : private T {
    using T::operator();
};

template <class T1, class T2, class... Ts>
struct overload<T1, T2, Ts...> : private T1, overload<T2, Ts...> {
    using T1::operator();
    using overload<T2, Ts...>::operator();
};
模板
结构重载{};//仅用于空包装
模板
结构重载:私有T{
使用T::operator();
};
模板
结构重载:私有T1,重载{
使用T1::operator();
使用重载::运算符();
};

布莱恩的答案更好,伊姆霍,但既然我做了,我的答案是:

#include <type_traits>
#include <utility>

template <typename... Fns>
struct overload;

template <typename Fn, typename... Fns>
struct overload<Fn, Fns...>
{
    template <typename... T>
    std::result_of_t<Fn(T...)> operator()(T && ... args) const {
        return Fn()(std::forward<T>(args)...);
    }

    using next = overload<Fns...>;

    template <typename... T>
    std::result_of_t<next(T...)> operator()(T && ... args) const {
        return next()(std::forward<T>(args)...);
    }
};
#包括
#包括
模板
结构过载;
模板
结构重载
{
模板
std::运算符()的结果(&&…args)常量{
返回Fn()(std::forward(args)…);
}
使用next=过载;
模板
std::运算符()的结果(&&…args)常量{
return next()(std::forward(args)…);
}
};

这可以使用模板专门化来完成:

#include <string>
#include <iostream>
template <typename...Args>
struct overload{

};
template <> struct overload<int>{
    int operator()(int x) const { return x + 1; }
};
template <> struct overload< std::string>{
    std::string operator()(const std::string& s) const { return s + s; }
};
template <typename...Args >
auto f(Args...arg){
    overload<Args...> func;
    return func(arg...);
}
int main()
{
    std::cout << f(3) << std::endl << f(std::string("Hello"));    
}
#包括
#包括
模板
结构重载{
};
模板结构重载{
int运算符()(int x)常量{return x+1;}
};
模板结构重载{
std::string操作符()(const std::string&s)const{return s+s;}
};
模板
自动f(Args…arg){
过载函数;
返回函数(参数…);
}
int main()
{

std::cout 3个重载的组合如何使用这种语法?
重载
?或者
重载
?@XerenNarcy我认为这两种设计都可以工作。
重载在我看来像嵌套对,而
重载
让我想起元组(所以我们cat做了
重载\u cat
或者类似的事情)。甚至有一种方法可以将类似的东西纳入标准。它还没有为C++17做好准备,但它正在为C++20做好准备。还有一个[参考实现]。()哇,我实际上并不认为这是真正可以做到的。令人印象深刻。更好的是,它有一个定义良好的分辨率顺序。