std::enable_if_t typedef 替换不等效

问题描述 投票:0回答:1

我经常为类创建

this_type
typedef 以缩短成员函数签名。 然而,我在使用
std::enable_if_t
时遇到了这个奇怪的情况。

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

template <class T, class Enable = void>
struct foo;

template <class T>
struct foo <T, std::enable_if_t<std::is_arithmetic_v<T>>>
{
    T data {};
    //typedef foo<T, void> this_type; // <-- can't do this
    //typedef foo<T, std::enable_if_t<true>> this_type; // <- can't do this either

    typedef foo<T, std::enable_if_t<std::is_arithmetic_v<T>>> this_type; // have to do this
    foo () = default;
    explicit foo(T i): data(i) {}
    foo (this_type const &) = default;
};

你不能在

this_type
的定义中使用完全等价的类型——当然,错误是
foo (this_type const &)
不能被默认,因为
this_type
与实际的类不匹配。

但它们都是同一类型:

int main(void)
{
    std::boolalpha(std::cout);
    std::cout << "enable_if_t: " << typeid(std::enable_if_t<std::is_arithmetic_v<int>>).name() << '\n';
    foo<int> myfoo{1};
    std::cout << "Same: " << std::is_same_v<decltype(myfoo), foo<int, void>> << '\n';
    std::cout << typeid(decltype(myfoo)).name() << '\n';
    std::cout << typeid(foo<int, void>).name() << '\n';
    std::cout << typeid(foo<int>::this_type).name() << '\n';

    foo<int> myfoo2(myfoo);
    return 0;
}

海湾合作委员会输出:

enable_if_t: v
Same: true
3fooIivE
3fooIivE
3fooIivE

一旦专业化成功,编译器就应该知道这一点:

std::enable_if_t
的结果立即被类型替换,在本例中为
void
。示例输出证实了这一点。

我认为这可能与旧的 C++ 标准在名称空间范围内相同类型的 typedef 之间产生的问题有关,但这不是原因,因为否则

typedef foo<T, std::enable_if_t<true>> this_type
会起作用。

是什么阻止了较短的类型别名被识别?

c++ templates typedef sfinae enable-if
1个回答
0
投票

您可以简单地将其定义为

typedef foo this_type;
// or
using this_type = foo;
在这种情况下,

foo
是一个注入类名,它指的是
foo
的当前专业化。 无需显式提供模板参数。

© www.soinside.com 2019 - 2024. All rights reserved.