简体   繁体   English

c ++ std::enable_if .... 其他?

[英]c++ std::enable_if .... else?

#include <stdio.h>
#include <type_traits>

void print()
{
    printf("cheers from print !\n");
}

class A 
{
  public:
  void print()
  {
      printf("cheers from A !");
  }
};


template<typename Function>
typename std::enable_if< std::is_function< 
                                typename std::remove_pointer<Function>::type >::value,
                                void >::type 
run(Function f)
{
    f();
}


template<typename T>
typename std::enable_if< !std::is_function< 
                                typename std::remove_pointer<T>::type >::value,
                                void >::type 
run(T& t)
{
    t.print();
}



int main()
{
    run(print);

    A a;
    run(a);

    return 0;
}

The code above compiles and print as expected:上面的代码按预期编译和打印:

cheers from print !来自印刷的欢呼! cheers from A !来自A的欢呼!

what I would like to express is : "if the template is function then apply this function, else ...".我想表达的是:“如果模板是函数,那么应用这个函数,否则......”。 Or in another formulation : having a version of the function for function templates, and a default version for non function templates.或者在另一种表述中:具有用于函数模板的函数版本,以及用于非函数模板的默认版本。

so, this part seems somehow redundant, and could be "replaced" by a "else" condition :所以,这部分似乎有些多余,可以用“其他”条件“替换”:

template<typename T>
typename std::enable_if< !std::is_function< 
                                typename std::remove_pointer<T>::type >::value,
                                void >::type 
run(T& t)

would this exists ?这会存在吗?

What you are looking for is constexpr if .您正在寻找的是constexpr if That will let you write the code like这会让你写出这样的代码

template<typename Obj>
void run(Obj o)
{
    if constexpr (std::is_function_v<std::remove_pointer_t<Obj>>)
        o();
    else
        o.print();
}

Live Example现场示例

If you don't have access to C++17 but do have C++14, you can at least shorten the code you need to write using a variable template .如果您无权访问 C++17 但有 C++14,则至少可以使用变量模板缩短需要编写的代码。 That would look like那看起来像

template<typename T>
static constexpr bool is_function_v = std::is_function< typename std::remove_pointer<T>::type >::value;

template<typename Function>
typename std::enable_if< is_function_v<Function>, void>::type 
run(Function f)
{
    f();
}


template<typename T>
typename std::enable_if< !is_function_v<T>, void>::type 
run(T& t)
{
    t.print();
}

Live Example现场示例

You can use the tag dispatch mechanism if you are limited to using C++11.如果您仅限于使用 C++11,则可以使用标签调度机制。

namespace detail
{
   template<typename Function>
   void run(std::true_type, Function& f)
   {
      f();
   }

   template<typename Object>
   void run(std::false_type, Object& o)
   {
      o.print();
   }

} // namespace detail

template<typename T>
void run(T& t)
{
   constexpr bool t_is_a_function = 
      std::is_function<typename std::remove_pointer<T>::type >::value;
   using tag = std::integral_constant<bool, t_is_a_function>;
   detail::run(tag{}, t);
}

Working example .工作示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM