【问题标题】:Compile error when doing SFINAE practice做 SFINAE 练习时出现编译错误
【发布时间】:2018-08-21 02:53:31
【问题描述】:

我有一个关于 SFINAE 的问题,我遇到了一个意外的编译错误:) 这是我的代码: sfinae.h:

#include <iostream>
#include <type_traits>

template <typename T>
struct RouteManager
{

template <typename ROUTER, typename u = void>
struct hasMethod  : std::false_type
{
};

template <typename ROUTER>
struct hasMethod<ROUTER, decltype(&ROUTER::RouteAll, void())>  : std::true_type
{
};

void f() 
{
    f(hasMethod<ORDER_ROUTER>{});
}

void f(std::false_type)
{
    std::cout << "false type" << std::endl;
}

void f(std::true_type)
{
    order_router.RouteAll();
    std::cout << "true type" << std::endl;
}
using ORDER_ROUTER = typename T::ORDER_ROUTER;
ORDER_ROUTER order_router;
};

接下来是 sfinae.cpp:

#include "sfinae.h"

template <typename A>
struct RouterA
{
};

template <typename DERIVED>
struct Base{};

struct TestTypes : Base<TestTypes>
{
    using ORDER_ROUTER = RouterA<TestTypes>;
};


template <typename B>
struct RouterB
{
    void RouteAll(){std::cout << "cancelAll";}
};

template class RouteManager<TestTypes> ;
int main()
{
}

当我编译此代码时,出现错误并显示“错误:'using ORDER_ROUTER = using ORDER_ROUTER = struct RouterA {aka struct RouterA}' has no member named 'RouteAll'”,我知道这是因为template class RouteManager&lt;TestTypes&gt;;但它不应该被定义为 f(std::false_type) 吗?

【问题讨论】:

  • 在定义 TestTypes 期间,您开始定义一个类型别名,该别名需要用于创建您希望它为其别名的类型。` 使用 ORDER_ROUTER = RouterA;` - 当它要弄清楚 RouterA 的类型是什么时,它必须返回并找到它仍在尝试制作的 ORDER_ROUTER 的类型。

标签: c++ templates overloading sfinae


【解决方案1】:

SFINAE 仅适用于替换 模板本身的模板参数。 f 是类模板的成员,它甚至不是模板本身,并且您试图替换其封闭类模板的模板参数,因此没有 SFINAE。

此外,非正式地,SFINAE 仅出现在模板的签名中,而不出现在模板的定义中。

使用 C++17,您可以使用 if constexpr:

void f() 
{
    if constexpr (hasMethod<ORDER_ROUTER>{}) {
        order_router.RouteAll();
        std::cout << "true type" << std::endl;
    }
    else std::cout << "false type" << std::endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多