如何使用sfinae选择构造函数? [英] How to use sfinae for selecting constructors?

查看:88
本文介绍了如何使用sfinae选择构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在模板元编程中,可以在返回类型上使用SFINAE来选择某个模板成员函数,例如

  template< int N> struct A {
int sum()const noexcept
{return _sum< N-1>(); }
private:
int _data [N];
template< int I> typename std :: enable_if< I,int> :: type _sum()const noexcept
{return _sum< I-1>()+ _data [I] }
template< int I> typename std :: enable_if<!I,int> :: type _sum()const noexcept
{return _data [I]; }
};

但是,这对构造函数不起作用。假设,我想声明构造函数

  template< int N& struct A {
/ * ... * /
template< int otherN>
explicit(A< otherN> const&); // only sensible if otherN> = N
};

但不允许 otherN<因此,可以在这里使用SFINAE吗?我只对允许自动模板的解决方案感兴趣。 - 参数扣除,使得

  A 4 a4 {}; 
A< 5> a5 {};
A< 6> a6 {a4}; //不编译
A< 3> a3 {a5}; //编译并自动找到正确的构造函数

注意:这是一个非常简化的示例, SFINAE可能过分,并且 static_assert 可能就足够了。但是,我想知道我是否可以使用SFINAE。

解决方案

You可以为模板添加默认类型参数:

  template< int otherN,typename = typename std :: enable_if< otherN> ; = N> :: type> 
explicit A(A< otherN> const&);


In template meta programming, one can use SFINAE on the return type to choose a certain template member function, i.e.

template<int N> struct A {
  int sum() const noexcept
  { return _sum<N-1>(); }
private:
  int _data[N];
  template<int I> typename std::enable_if< I,int>::type _sum() const noexcept
  { return _sum<I-1>() + _data[I]; }
  template<int I> typename std::enable_if<!I,int>::type _sum() const noexcept
  { return _data[I]; }
};

However, this doesn't work on constructors. Suppose, I want to declare the constructor

template<int N> struct A {
   /* ... */
   template<int otherN>
   explicit(A<otherN> const&); // only sensible if otherN >= N
};

but disallow it for otherN < N.

So, can SFINAE be used here? I'm only interested in solutions which allow automatic template-parameter deduction, so that

A<4> a4{};
A<5> a5{};
A<6> a6{a4};  // doesn't compile
A<3> a3{a5};  // compiles and automatically finds the correct constructor

Note: this is a very simplified example where SFINAE may be overkill and static_assert may suffice. However, I want to know whether I can use SFINAE instead.

解决方案

You can add a defaulted type argument to the template:

template <int otherN, typename = typename std::enable_if<otherN >= N>::type>
explicit A(A<otherN> const &);

这篇关于如何使用sfinae选择构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆