You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现可调用对象返回类型提取Trait时的SFINAE错误排查

问题:SFINAE实现可调用对象返回类型提取失败

背景

我正在练习SFINAE技术,尝试获取各类可调用对象(函数、函数指针、lambda、重载()运算符的对象)的相关信息,编写了如下代码:

#include <iostream>
#include <functional>
#include <string>
#include <type_traits>

template<typename Callable, typename = void>
struct function_type_info;

template<typename R, typename G, typename... T>
struct function_type_info<R(G::*)(T...)> {
    using return_type = R;
};

template<typename C>
struct function_type_info<C, typename std::enable_if<!std::is_member_function_pointer<C>::value, C>::type> {
    using return_type = typename function_type_info<decltype(&C::operator())>::return_type;
};

struct Callback {
    int operator()(double, std::string) {
        return 0;
    }
};

int main(int argc, char** argv) {
    auto b = [](double, std::string) -> int { return 0; };
    auto c = Callback{};

    std::cout << std::boolalpha;

    std::cout << std::is_same<function_type_info<decltype(&Callback::operator())>::return_type, int>::value << std::endl;
    std::cout << std::is_same<function_type_info<decltype(b)>::return_type, int>::value << std::endl;
    std::cout << std::is_same<function_type_info<decltype(c)>::return_type, int>::value << std::endl;

    return 0;
}

初始编译错误

编译器报出如下错误:

<source>:32:64: error: incomplete type 'function_type_info<main(int, char**)::<lambda(double, std::string)> >' used in nested name specifier
   32 |     std::cout << std::is_same<function_type_info<decltype(b)>::return_type, int>::value << std::endl;
      |                                                                ^~~~~~~~~~~
<source>:32:80: error: template argument 1 is invalid
   32 |     std::cout << std::is_same<function_type_info<decltype(b)>::return_type, int>::value << std::endl;
      |                                                                                ^
<source>:33:64: error: incomplete type 'function_type_info<Callback>' used in nested name specifier
   33 |     std::cout << std::is_same<function_type_info<decltype(c)>::return_type, int>::value << std::endl;
      |                                                                ^~~~~~~~~~~
<source>:33:80: error: template argument 1 is invalid
   33 |     std::cout << std::is_same<function_type_info<decltype(c)>::return_type, int>::value << std::endl;

调试后的问题

我无法理解错误原因:对于lambda和Callback对象,第二个function_type_info特化应该被匹配,因为std::is_member_function_pointer<C>::value为false,enable_if应生效。将enable_if的第二个参数改为void后,Callback可以正常工作,但lambda仍报错,错误信息如下:

<source>: In instantiation of 'struct function_type_info<main(int, char**)::<lambda(double, std::string)> >':
<source>:32:62:   required from here
<source>:16:11: error: invalid use of incomplete type 'struct function_type_info<int (main(int, char**)::<lambda(double, std::string)>::*)(double, std::__cxx11::basic_string<char>) const, void>'
   16 |     using return_type = typename function_type_info<decltype(&C::operator())>::return_type;
      |           ^~~~~~~~~~~
<source>:7:8: note: declaration of 'struct function_type_info<int (main(int, char**)::<lambda(double, std::string)>::*)(double, std::__cxx11::basic_string<char>) const, void>'
    7 | struct function_type_info;
      |        ^~~~~~~~~~~~~~~~~~
<source>: In function 'int main(int, char**)':
<source>:32:80: error: template argument 1 is invalid
   32 |     std::cout << std::is_same<function_type_info<decltype(b)>::return_type, int>::value << std::endl;

补充说明

仿佛无法访问lambda的()运算符。注:我知道可用std::result_of/std::invoke_result实现,但这是练习。


内容的提问来源于stack exchange,提问作者sunmat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:05:06