发布
社区首页 >问答首页 >使用模板重载函数-仅当存在替代函数时才应用enable_if

使用模板重载函数-仅当存在替代函数时才应用enable_if
EN

Stack Overflow用户
提问于 2019-09-22 19:45:30
回答 1查看 180关注 0票数 1

我设法根据对象的等级重载std::ostream的插入运算符。我想扩展一下下面的例子。

当包含A_new.h时,它包含A.h...在本例中,我检查对象的等级,并调用f_alterantivef_old。按预期工作:)

当直接包含A.h,然后只有一个f() - f_old实例时,就会出现问题。

如果只有一个直接通过A.h包含的f()实例,那么它应该是所有对象的默认实例...(不仅对于rank > 1,而且对于所有rest)和低于条件没有任何意义。

代码语言:javascript
代码运行次数:0
复制
typename std::enable_if <(std::rank<T>::value > 1), int>::type = 0 >

我知道我需要指定检查另一个f()是否存在的条件:类似于:

代码语言:javascript
代码运行次数:0
复制
//goal:    typename std::enable_if <((f_alternative_exist == false) || (std::rank<T>::value > 1 && f_alternative_exist == true) ), int>::type = 0 >

我找到了similar question,但我仍然不确定如何使用std::enable_if

代码语言:javascript
代码运行次数:0
复制
#include <iostream>
#include <type_traits>
#include <sstream>

class Foo {
};
    //--- alternative header A_new.h
    //#include A.h
    template< class T,
             typename std::enable_if<(std::rank<T>::value == 1), int>::type = 0 >
    void f(std::ostream& os, const T& value)
    //f_alternative 
    {
        os << "alternative function\n";
        os << "rank == 1" << std::endl;
    }
    //----

    //---- old header A.h
    template < class T,
               typename std::enable_if <(std::rank<T>::value > 1), int>::type = 0 >
    //goal:    typename std::enable_if <((f_alternative_exist == false) || (std::rank<T>::value > 1 && f_alternative_exist == true) ), int>::type = 0 >
    void f(std::ostream& os, const T& value)
    //f_old
    {
        os << "old function\n";
        os << "rank > 1" << std::endl;
    }

    template <class T>
    std::ostream& operator<<(std::ostream& os, const T& foo)
    {
        f<T>(os, foo);
        return os;
    }
    //-----

int main()
{
    Foo foo1[5];
    Foo foo2[5][5];

    std::cout << foo1; 
    std::cout << foo2;

    return 0;
}

https://coliru.stacked-crooked.com/a/7f7ef7bda1805a36

你能告诉我,当f()没有过载时,我如何指定std::enable_if也可以工作,以及它应该在所有情况下运行的时间?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-22 20:14:43

可能的f_alternative_exist如下所示

代码语言:javascript
代码运行次数:0
复制
template <typename T>
std::false_type f_alternative_exist_f (std::ostream &, T const &, long);

template <typename T>
auto f_alternative_exist_f (std::ostream & os, T const & t, int)
   -> decltype( f(os, t), std::true_type{} );

template <typename T>
using f_alternative_exist
   = decltype(f_alternative_exist_f(std::declval<std::ostream &>(),
                                    std::declval<T>(), 0));

template <typename T>
static constexpr bool f_alternative_exist_v
   = f_alternative_exist<T>::value;

旧版本变成了

代码语言:javascript
代码运行次数:0
复制
template <typename T, 
          std::enable_if_t<(std::rank<T>::value > 1)
                        || (false == f_alternative_exist_v<T>), int> = 0 >
void f (std::ostream & os, T const &)
 {
   os << "old function\n";
   os << "rank > 1" << std::endl;
 }

以下是一个完整的编译C++14示例

代码语言:javascript
代码运行次数:0
复制
#include <iostream>
#include <type_traits>
#include <sstream>

class Foo
 { };

template <typename T>
std::false_type f_alternative_exist_f (std::ostream &, T const &, long);

template <typename T>
auto f_alternative_exist_f (std::ostream & os, T const & t, int)
   -> decltype( f(os, t), std::true_type{} );

template <typename T>
using f_alternative_exist
   = decltype(f_alternative_exist_f(std::declval<std::ostream &>(),
                                    std::declval<T>(), 0));

template <typename T>
static constexpr bool f_alternative_exist_v
   = f_alternative_exist<T>::value;

#if 0 // enable/disable
template <typename T,
          std::enable_if_t<std::rank<T>::value == 1, int> = 0 >
void f (std::ostream & os, T const &)
 {
   os << "alternative function\n";
   os << "rank == 1" << std::endl;
 }
#endif

template <typename T, 
          std::enable_if_t<(std::rank<T>::value > 1)
                        || (false == f_alternative_exist_v<T>), int> = 0 >
void f (std::ostream & os, T const &)
 {
   os << "old function\n";
   os << "rank > 1" << std::endl;
 }

template <typename T>
std::ostream& operator<<(std::ostream& os, const T& foo)
 {
   f<T>(os, foo);
   return os;
 }

int main ()
 {
   Foo foo1[5];
   Foo foo2[5][5];

   std::cout << foo1; 
   std::cout << foo2;
 }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58048902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档