我通常会声明我的类和模板,然后在(在相同的头文件中)之后定义它们的方法。我发现这种方式更容易阅读。好吧,我遇到过一个案例,我无法弄清楚在一个类外定义中使用的工作类型签名。这是我正在做的一个简化示例,它说明了问题:
template <class T>
struct Foo
{
Foo(T a, T b);
template
< class Iterator
, enable_if< is_iterator<Iterator> >
>
Foo
( Iterator first
, Iterator last
);
};
template <class T>
Foo<T>::Foo(T a, T b)
{ ... }
template <class T>
template
< class U
, WHAT_GOES_HERE?
>
Foo<T>::Foo(U f, U l)
{ ... }
我在WHAT_GOES_HERE
插槽中尝试了很多东西来尝试获得匹配的签名,但我一直都在失败。我需要enable_if来区分一个传入两个T类型对象的情况,以及一个传递一对迭代器的情况。如果在主模板中定义模板化构造函数,代码工作正常,这是代码当前的工作方式,但我更倾向于将定义移到声明之外。
编辑:我应该提一下,我不能只重复使用enable_if&lt; ...&gt;在定义中,因为enable_if&lt; ...&gt;为其类型指定一个默认值,您不能在也不是声明的定义中执行此操作。
答案 0 :(得分:3)
我不这样做。这是我要做的改变:
template <class T>
struct Foo
{
Foo(T a, T b);
template
< class Iterator
>
Foo
( Iterator first
, Iterator last
, typename enable_if<is_iterator<Iterator> >::type* = 0
);
};
template <class T>
Foo<T>::Foo(T a, T b)
{ ... }
template <class T>
template
< class U
>
Foo<T>::Foo(U f, U l, typename enable_if< is_iterator<U> >::type*)
{ ... }
这直接来自enable_if
的文档。
答案 1 :(得分:2)
这是你想要完成的吗? [我没有is_iterator
类型特征,因此我使用C ++ 0x类型特征和实用程序库重新设计了您的示例。它应该与TR1和Boost库的工作方式相同。]
#include <utility>
#include <type_traits>
template <typename T>
struct S
{
// Constructor (1)
S(T, T);
// Constructor (2)
template <typename U>
S(U, U, typename std::enable_if<std::is_integral<U>::value>::type* = 0);
};
template <typename T>
S<T>::S(T, T)
{ }
template <typename T>
template <typename U>
S<T>::S(U, U, typename std::enable_if<std::is_integral<U>::value>::type*)
{ }
int main()
{
S<double> a(1.0, 2.0); // uses (1)
S<double> b(1, 2); // uses (2)
}
答案 2 :(得分:1)
你能做的最简单的事是:
template<class Iterator>
Foo
( Iterator first
, typename enable_if<is_iterator<Iterator>, Iterator>::type last
);
答案 3 :(得分:1)
template <class T>
struct Foo
{
Foo(T a, T b);
template <class Iterator
, class = typename std::enable_if
<is_iterator<Iterator>::value>
::type
>
Foo
( Iterator first
, Iterator last
);
};
template <class T>
Foo<T>::Foo(T a, T b)
{ }
template <class T>
template
< class U
, class >
Foo<T>::Foo(U f, U l)
{ }