我一直在寻找解决我的问题超过堆栈溢出,并看到许多类似的主题,但没有答案指向如此具体的情况。
在附加的代码中,除非我取消注解#define ISSUE
,否则一切正常,然后我会得到很多错误。
这里的目标是能够只在类体中声明专门化。实现需要在类定义之后放在同一个文件中。
为什么这不起作用?如何使它起作用?
我的编译器支持C++17,没有更新。
#include <cstdint>
#include <iostream>
#include <type_traits>
// #define ISSUE
template <typename T>
class Test
{
public:
template<typename U = T,
std::enable_if_t<
std::is_same<T, bool>::value ||
std::is_same<T, int8_t>::value ||
std::is_same<T, uint8_t>::value ||
(std::is_enum<T>::value && (sizeof(T) == 1U))
,int> = 0>
static void special(T data);
#if defined(ISSUE)
template<typename U = T,
std::enable_if_t<
std::is_same<T, int32_t>::value ||
std::is_same<T, uint32_t>::value ||
(std::is_enum<T>::value && (sizeof(T) == 4U))
,int> = 0>
static void special(T data);
#endif
};
template <typename T>
template <typename,
std::enable_if_t<
std::is_same<T, bool>::value ||
std::is_same<T, int8_t>::value ||
std::is_same<T, uint8_t>::value ||
(std::is_enum<T>::value && (sizeof(T) == 1U))
,int>>
void Test<T>::special(T data)
{
std::cout << "print 8-bit\n";
}
#if defined(ISSUE)
template <typename T>
template <typename,
std::enable_if_t<
std::is_same<T, int32_t>::value ||
std::is_same<T, uint32_t>::value ||
(std::is_enum<T>::value && (sizeof(T) == 4U))
,int>>
void Test<T>::special(T data)
{
std::cout << "print 32-bit\n";
}
#endif
int main()
{
Test<uint8_t>{}.special(5);
Test<int8_t>{}.special(5);
Test<bool>{}.special(true);
#if defined(ISSUE)
Test<uint32_t>{}.special(5);
Test<int32_t>{}.special(5);
#endif
}
仅限帖子:
How to use std::enable_if on method of templated class with seperate declaration and definition via specialization
帮助了一点,得到了什么与#define ISSUE
注解了。
1条答案
按热度按时间5sxhfpxr1#
为什么这不起作用?
首先,它们只是模板函数重载,而不是成员函数的特殊化。
SFINAE只能在
std::enable_if_t
的条件依赖于函数的模板参数类型时工作。这意味着,在您显示的代码中,它必须依赖于U
,而不是类模板参数T
。除此之外,
std::enable_if_t
的第二个参数是函数的返回类型,它将是SFINAEd。您已经提供了int
作为返回,它必须是void
(或者不提供,因为它是std::enable_if_t
的默认类型)。如何让它发挥作用?
我提出了另一种方法,直接在函数签名中使用
std::enable_if_t
作为返回类型,而不是在模板参数列表中。你仍然可以把函数的定义单独保存在类之外。
See live demo godbolt.org
话虽如此,由于您可以访问C++17编译器,因此可以查看
if constexpr
,这是该场景的更好替代方案。或者使用fold expression,您也可以简化扩展的std::enable_if
条件,如下所示:See live demo godbolt.org