因此,基本上,我现在有一个非常基本的泛型类,目前正在测试type_traits头。目前,我正在尝试制作一个函数来处理某些类型的函数,即目前使用的算术函数。
#include <type_traits>
template <typename T> class Test {
public:
template <typename U = T>
typename std::enable_if<std::is_arithmetic<U>::value>::type print();
}; 该函数工作良好,仅适用于算术类型。
但我喜欢保持类的整洁,只让它们具有原型,而函数实现则在类之外。
使用标准模板,例如
void test();
template <typename T> void Test<T>::test() {}这很简单,我知道如何做,但是我不知道如何用"std::enable_if“来声明类之外的实现,我在编译过程中所做的每一次尝试都说原型与类中的任何一个都不匹配。
我在这里找到了一个类似的问题,但是那里的类是标准的,而不是泛型的。
PS。我在-std=c++17中使用MinGW-w64
发布于 2018-01-27 21:04:07
类模板需要一组模板参数,成员函数模板需要一组单独的模板参数。您需要重复整个复杂的返回类型,因为它是函数模板签名的一部分。请注意,您不能重复默认参数=T,否则编译器会认为您试图两次定义它(而不检查新定义是否相同)。
template <typename T> template <typename U>
typename std::enable_if<std::is_arithmetic<U>::value>::type
Test<T>::print()
{
// Implementation here.
}顺便说一句,您使用的是编写类型的“漫长的方式”,这在C++11中是需要的,但是C++14引入了std::enable_if_t快捷方式,C++17引入了std::is_arithmetic_v快捷方式。因此,如果使用C++17,还可以编写以下类型
typename std::enable_if<std::is_arithmetic<U>::value>::type就像
std::enable_if_t<std::is_arithmetic_v<U>>发布于 2018-01-27 21:40:22
如果您将enable_if放在默认的模板参数中,这是imo更好的,那么类外定义就会变得更容易一些:
template<typename T>
struct Test
{
template <typename S = T
, typename = typename std::enable_if<std::is_arithmetic<S>::value>::type >
void print();
};
template<typename T>
template<typename S, typename>
void Test<T>::print()
{
//some code
}发布于 2018-01-27 21:02:57
你可以试试
template <typename T>
template <typename U>
std::enable_if_t<std::is_arithmetic<U>::value> Test<T>::print()
{ /* do something */ }下面是一个完整的工作示例
#include <iostream>
#include <type_traits>
template <typename T> class Test
{
public:
template <typename U = T>
std::enable_if_t<std::is_arithmetic<U>::value> print();
};
template <typename T>
template <typename U>
std::enable_if_t<std::is_arithmetic<U>::value> Test<T>::print()
{ std::cout << "test!" << std::endl; }
int main ()
{
Test<int> ti;
Test<void> tv;
ti.print(); // compile
//tv.print(); // compilation error
}离题1
请注意,您的解决方案可能以这种方式被劫持。
Test<void>{}.print<int>(); 为了避免这个问题,您可以强制要求T等于U,
template <typename T> class Test
{
public:
template <typename U = T>
std::enable_if_t< std::is_arithmetic<U>::value
&& std::is_same<T, U>::value> print()
{ }
}; 离题2
如您所见,您必须重复SFINAE部分(std::enable_if_t、std::is_arithmetic和std::is_same)。
考虑到您必须在标题中重复实现,我不认为(IMHO)在类的主体之外编写模板类的实现是一个好主意。
https://stackoverflow.com/questions/48480469
复制相似问题