如何使用默认模板参数分离模板化 class 的声明和实现?
How to seperate declaration and implementation of a templated class with a default template parameter?
我喜欢将 classes 的声明和实现分开。我知道 class 模板和函数的实现也必须进入头文件,这不是问题。
我在实现这个时遇到了问题 class:
template <size_t S, std::enable_if_t<(S > 0), int> = 0>
class Foo {
public:
Foo();
}
到目前为止我已经尝试过:
template<size_t S>
Foo<S>::Foo() {}
失败
error C3860: template argument list following class template name must list parameters in the order used in template parameter list
error C2976: 'Foo<S,<__formal>>' : too few template arguments
和
template<size_t S, int i>
Foo<S, i>::Foo() {}
失败
error C3860: template argument list following class template name must list parameters in the order used in template parameter list
error C3855: 'Foo<S,<unnamed-symbol>>' : template parameter '__formal' is incompatible with the declaration
我也试过将模板声明更改为
template <size_t S, typename = std::enable_if_t<(S > 0)>>
也失败并显示第一条错误消息。
正确的做法是什么?
您不能部分特化模板函数(这是您在第一个片段中所做的)。如果您询问如何在 class 之外定义它,试试这个:
template <size_t S, std::enable_if_t<(S > 0), int> j>
Foo<S, j>::Foo(){}
您不能仅将 std::enable_if_t<(S > 0), int>
替换为 int
,因为定义不相同(enable_if
一个 SFINAE 出 S == 0
案例)。
What is the correct way of doing this?
我想你试过的第二个是 typename
。
给出
template <size_t S, typename = std::enable_if_t<(S > 0)>>
class Foo {
public:
Foo();
};
构造函数可以定义为
template <std::size_t S, typename T>
Foo<S, T>::Foo() {}
一个完整的编译示例
#include <iostream>
#include <type_traits>
template <size_t S, typename = std::enable_if_t<(S > 0)>>
class Foo {
public:
Foo();
};
template <std::size_t S, typename T>
Foo<S, T>::Foo() {}
int main ()
{
Foo<12U> f12; // compile
// Foo<0U> f0; // compilation error
}
保持简单:
template <size_t S>
class Foo {
public:
Foo();
};
template <size_t S>
Foo<S>::Foo() { }
template <>
class Foo<0>;
在这种特殊情况下,我不确定添加 SFINAE 是否会给您带来任何额外好处。有可能甚至不需要显式特化,只需一个简单的 static_assert(S > 0, "!")
就足够了。
我喜欢将 classes 的声明和实现分开。我知道 class 模板和函数的实现也必须进入头文件,这不是问题。
我在实现这个时遇到了问题 class:
template <size_t S, std::enable_if_t<(S > 0), int> = 0>
class Foo {
public:
Foo();
}
到目前为止我已经尝试过:
template<size_t S>
Foo<S>::Foo() {}
失败
error C3860: template argument list following class template name must list parameters in the order used in template parameter list
error C2976: 'Foo<S,<__formal>>' : too few template arguments
和
template<size_t S, int i>
Foo<S, i>::Foo() {}
失败
error C3860: template argument list following class template name must list parameters in the order used in template parameter list
error C3855: 'Foo<S,<unnamed-symbol>>' : template parameter '__formal' is incompatible with the declaration
我也试过将模板声明更改为
template <size_t S, typename = std::enable_if_t<(S > 0)>>
也失败并显示第一条错误消息。
正确的做法是什么?
您不能部分特化模板函数(这是您在第一个片段中所做的)。如果您询问如何在 class 之外定义它,试试这个:
template <size_t S, std::enable_if_t<(S > 0), int> j>
Foo<S, j>::Foo(){}
您不能仅将 std::enable_if_t<(S > 0), int>
替换为 int
,因为定义不相同(enable_if
一个 SFINAE 出 S == 0
案例)。
What is the correct way of doing this?
我想你试过的第二个是 typename
。
给出
template <size_t S, typename = std::enable_if_t<(S > 0)>>
class Foo {
public:
Foo();
};
构造函数可以定义为
template <std::size_t S, typename T>
Foo<S, T>::Foo() {}
一个完整的编译示例
#include <iostream>
#include <type_traits>
template <size_t S, typename = std::enable_if_t<(S > 0)>>
class Foo {
public:
Foo();
};
template <std::size_t S, typename T>
Foo<S, T>::Foo() {}
int main ()
{
Foo<12U> f12; // compile
// Foo<0U> f0; // compilation error
}
保持简单:
template <size_t S>
class Foo {
public:
Foo();
};
template <size_t S>
Foo<S>::Foo() { }
template <>
class Foo<0>;
在这种特殊情况下,我不确定添加 SFINAE 是否会给您带来任何额外好处。有可能甚至不需要显式特化,只需一个简单的 static_assert(S > 0, "!")
就足够了。