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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.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++11 T和返回T的函数对象的模板专门化_C++11_Templates - Fatal编程技术网

C++11 T和返回T的函数对象的模板专门化

C++11 T和返回T的函数对象的模板专门化,c++11,templates,C++11,Templates,是否有任何方法可以对函数进行模板化,以便它可以在泛型情况下接受T,或者如果模板参数解析为可调用的对象(例如函子、函数指针或std::function),则可以接受专门化 例如,我想要这样的东西: template<typename T> void use_this(T obj) { obj->do_stuff(); } template<> void use_this<???>(??? func) { use_this(func()); }

是否有任何方法可以对函数进行模板化,以便它可以在泛型情况下接受T,或者如果模板参数解析为可调用的对象(例如函子、函数指针或
std::function
),则可以接受专门化 例如,我想要这样的东西:

template<typename T>
void use_this(T obj) {
  obj->do_stuff();
}

template<>
void use_this<???>(??? func) {
  use_this(func());
}

use_this(MyObj); // should call first one
use_this([MyObj](){ return MyObj; }); // should call the second one
模板
无效使用此(目标){
obj->do_stuff();
}
模板
无效使用此(?func){
使用_this(func());
}
使用这个(MyObj);//我应该叫第一个
使用这个([MyObj](){return MyObj;});//应该叫第二个

您不能部分专门化函数模板,因此无法获得您在问题中指出的语法

您可以编写两个函数模板:一个用于
T
可无参数调用时,另一个用于不可调用时。然后,您可以使用禁用函数版本,并添加额外的函数参数,以使重载解析在可用时更倾向于该版本:

template<typename T>
void use_this(T obj, float) {
  obj->do_stuff();
}

template<typename Func>
auto use_this (Func func, int) -> decltype(func(), void()) {
  use_this(func());
}
模板
无效使用此(目标、浮动){
obj->do_stuff();
}
模板
自动使用_this(Func Func,int)->decltype(Func(),void()){
使用_this(func());
}
然后可以添加一个包装器,该包装器提供消歧参数本身:

template <typename T>
void use_this(T&& t) {
    use_this(std::forward<T>(t), 0);   
}
模板
无效使用此(T&T){
使用这个(std::forward(t),0);
}

我使用了一些C++11,例如
启用if\u t
无效\u t
结果\u t
。所有这些都很容易用C++11编写,也很容易搜索

当传递无效签名时,的
result\u的行为在C++14中发生了更改。在C++11中,它不必是SFINAE友好的。我们可以用C++11中的
invoke\u result\r
替换
std::result\u of \u t
,如下所示:

template<class Sig, class=void>
struct invoke_result {};
template<class Sig>
using invoke_result = typename invoke_result<Sig>::type;

template<class F, class...Args>
struct invoke_result<F(Args...),
  decltype( void( std::declval<F>()( std::declval<Args>()... ) ) )
> {
  using type = decltype( std::declval<F>()( std::declval<Args>()... ) );
};
模板
结构调用_结果{};
模板
使用invoke_result=typename invoke_result::type;
模板
结构调用结果{
使用type=decltype(std::declval()(std::declval()…);
};
这是斯芬纳友好型的

可以应用
类似于C++20的
被检测到
,但较短且切中要害

请注意,在非C++11编译器(如MSVC)中执行此操作是不切实际的。但是,您可以使用标记分派执行类似的操作

template<class T>
std::enable_if_t< !can_invoke<T()> >
use_this( T obj ) {
  obj->do_stuff();
}
template<class T>
std::enable_if_t< can_invoke<T()> >
use_this( T func ) {
  use_this( func() );
}
template<class Sig, class=void>
struct invoke_result {};
template<class Sig>
using invoke_result = typename invoke_result<Sig>::type;

template<class F, class...Args>
struct invoke_result<F(Args...),
  decltype( void( std::declval<F>()( std::declval<Args>()... ) ) )
> {
  using type = decltype( std::declval<F>()( std::declval<Args>()... ) );
};