有没有从双到std隐式转换的方式::阵列 ?

问题描述 投票:4回答:5

我有一个模板类是这样的:

template<int dimension>
class Foo{
  Foo(std::array<double, dimension>);
}

和功能

func(Foo<1> f);

我希望能够调用该函数和像这样的构造:

func(1);
Foo<1> f(1);

代替

func({1});
Foo<1> f({1});

有没有一个好的方法来实现这一目标?

如果隐式转换是不可能的,可以加1只为Foo<1>情况下,一个构造函数?

c++ implicit-conversion stdarray
5个回答
8
投票

对于doublestd::array<double, 1>的隐式转换是不可能的。这就需要对超载一double转换操作符,但不能做,你不能超载运营商内置类型。

你可以做的就是添加

Foo(double);

构造函数,然后使用像static_assert

static_assert(dimension == 1, "single double constructor only works if dimension == 1");

在构造函数体来限制它,当数组的大小1的只有工作。 (我喜欢使用static_assert时,我可以,因为它可以让你写一个很好的描述,错误消息)


你应该考虑重新命名dimensionsize,因为这是在数组中指定。


5
投票

您可以定义另一个重载的构造函数,然后使用委派,例如像这样:

template<int dimension>
class Foo{
  public:
    Foo(std::array<double, dimension>) {}
    Foo(double init) : Foo(std::array<double, dimension>{{init}}) {}
};

这样一来,既所需调用

func(1);
Foo<1> f(1);

将工作。


2
投票

稍微目前存在的方法是使用可变参数模板的构造函数。在其他解决方案的好处是,你的类不拥有一个构造函数,会导致编译错误(意外地呼吁Foo尺寸小于1高单双层构造函数)。

template <int dimension>
class Foo {
 public:
  Foo(std::array<double, dimension>) {}

  template <typename... Is>
  Foo(Is... inits) : Foo{std::array<double, sizeof...(Is)>{inits...}} {}
};

Foo<1> f1(1.);
Foo<2> f2(1., 2.);

缺点是,你必须使用std::array时显式调用构造函数。


0
投票

而另一个版本直接转发到您的存储变量。

template <int dimension>
class Foo {
public:
    std::array<double, dimension> data;

    template< class... Args >
    Foo(Args&&... args) : data{std::forward<Args>(args)...} {}
};

Foo<1> one(1.);
Foo<2> two(1., 2.);
// Foo<2> three(1., 2., 3.); // error: too many initializers for

0
投票

事情是这样的:

#include <array>
#include <iostream>
#include <type_traits>

template < int dimension >
struct Foo
{
  Foo(std::array< double, dimension > x)
  : store_(x)
  {
    std::cout << "array\n";
  }

  template < class... Args, std::enable_if_t< sizeof...(Args) == dimension > * = nullptr >
  Foo(Args &&... args)
  : store_ { { double(args)... } }
  {
    std::cout << "items\n";
  }

  std::array< double, dimension > store_;
};

template < class... Ts >
auto use(Ts &&...)
{
}

int main()
{
  auto f1 = Foo< 1 >(std::array< double, 1 > { 1.0 });
  auto f2 = Foo< 1 >(1.0);

  use(f1);
  use(f2);

  auto f4 = Foo< 3 >(std::array< double, 3 > { 1.0, 2.0, 3 });
  auto f3 = Foo< 3 >(1, 2, 3);
  use(f3, f4);
}
© www.soinside.com 2019 - 2024. All rights reserved.