【问题标题】:How to slove this error when using enable_if: "no type named ‘type’ in ‘struct std::enable_if<false, void>’"使用 enable_if 时如何解决此错误:“‘struct std::enable_if<false, void>’中没有名为‘type’的类型”
【发布时间】:2021-03-25 16:48:29
【问题描述】:

我想用T的不同类型调用pushArg()方法。

这里是相关代码sn-p:

//test.hpp
struct Demo {int a};

typedef int (*CALL_CFunction)(struct Demo* );

classs Ctx
{
    /*push bool */
    template <typename T, 
              typename std::enable_if<std::is_integral<T>::value>::type* = nullptr,
              typename std::enable_if<std::is_same<T, bool>::value>::type* = nullptr>
    int pushArg(T& val)
    {
        std::std << "push bool" <<std::endl;  
        return 0;
    }

    /*push lua_CFunction*/
    template <typename T, 
          typename std::enable_if<std::is_pointer<T>::value>::type* = nullptr,
          typename std::enable_if<std::is_same<CALL_CFunction, T>::value>::type* = nullptr>
    int pushArg(T& val)
    {
        std::cout << "push function" << std::endl;
        return 0;
    }
}

调用pushArg()的函数:

int foo(Struct Demo *) {return 0;}
Ctx ctx;
ctx.pushArg(foo);

以下是错误信息:

  test.cpp:36:22: error: no matching function for call to ‘ctx::pushArg(int (&)(lua_State*))’
      pCtx->pushArg(foo);
                          ^
    In file included from test.cpp:1:0:
    test.hpp:131:9: note: candidate: template<class T, typename std::enable_if<std::is_integral<_Tp>::value>::type* <anonymous>, typename std::enable_if<std::is_same<T, bool>::value>::type* <anonymous> > int ctx::pushLuaArg(T&)
         int pushLuaArg(T& val)
             ^
    test.hpp:131:9: note:   template argument deduction/substitution failed:
    test.hpp:129:76: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
               typename std::enable_if<std::is_integral<T>::value>::type* = nullptr,
                                                                            ^

【问题讨论】:

    标签: c++ c++11 templates enable-if


    【解决方案1】:

    pushArg的参数val声明为pass-by-reference,然后给定ctx.pushArg(foo);,函数到指针的衰减不会发生,T推导出为函数类型,即@ 987654325@。对于第二次重载,std::is_pointer&lt;T&gt;::valuestd::is_same&lt;CALL_CFunction, T&gt;::value 都会产生 false

    对于std::is_pointer,您可以改用std::is_function,但这似乎是多余的。只需std::is_same 就足够了。 (如果std::is_same&lt;CALL_CFunction, T*&gt;::value 给出true,那么std::is_function&lt;T&gt;::value 也将是true。)例如

    template <typename T, 
              typename std::enable_if<std::is_same<CALL_CFunction, T*>::value>::type* = nullptr>
    //                                                              ^
    int pushArg(T& val)
    

    【讨论】:

    • 为什么是std::is_same&lt;lua_CFunction, T*&gt;::value,而不是std::is_same&lt;lua_CFunction, T&gt;::value?能否请您为我详细解释一下?
    • @John 函数类型和函数指针类型不是一回事。在被std::is_same比较时,它们必须匹配。
    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2023-04-05
    • 2014-08-29
    相关资源
    最近更新 更多