std::array<> 的构造函数委托
Constructor delegation with std::array<>
我有一个 class,它在构造函数中接收一个 std::array
。对于我的生活,我无法从 std::initializer_list
中编写正确且简单的委托 - 只有我已经注释掉的笨拙的 lambda。谁能告诉我一个没有临时代码的干净合理的方法?
#include <array>
class foo
{
std::array<int,5> t_;
public:
foo(): foo{{}}
{ }
foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
// foo { [il]() {
// std::array<int,5> tmp;
// std::size_t i = 0;
// for (auto ile: il)
// if (i >= tmp.size()) break;
// else tmp[i++]=ile;
// return tmp;
// }()}
{ }
foo(std::array<int,5> t): t_(t)
{ }
};
这给出:
g++ -std=c++17 -pedantic -Wall -Wextra -c -o t.o t.cpp
t.cpp: In constructor 'foo::foo(std::initializer_list<int>)':
t.cpp:12:69: error: no matching function for call to 'std::array<int, 5>::array(std::initializer_list<int>&)'
12 | foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
| ^
In file included from t.cpp:1:
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate: 'std::array<int, 5>::array()'
94 | struct array
| ^~~~~
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate expects 0 arguments, 1 provided
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate: 'constexpr std::array<int, 5>::array(const std::array<int, 5>&)'
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: no known conversion for argument 1 from 'std::initializer_list<int>' to 'const std::array<int, 5>&'
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate: 'constexpr std::array<int, 5>::array(std::array<int, 5>&&)'
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: no known conversion for argument 1 from 'std::initializer_list<int>' to 'std::array<int, 5>&&'
t.cpp:12:71: error: no matching function for call to 'foo::foo(<brace-enclosed initializer list>)'
12 | foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
| ^
t.cpp:23:3: note: candidate: 'foo::foo(std::array<int, 5>)'
23 | foo(std::array<int,5> t): t_(t)
| ^~~
t.cpp:23:3: note: conversion of argument 1 would be ill-formed:
t.cpp:12:3: note: candidate: 'foo::foo(std::initializer_list<int>)'
12 | foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
| ^~~
t.cpp:12:3: note: conversion of argument 1 would be ill-formed:
t.cpp:9:3: note: candidate: 'foo::foo()'
9 | foo(): foo{{}}
| ^~~
t.cpp:9:3: note: candidate expects 0 arguments, 1 provided
t.cpp:3:7: note: candidate: 'constexpr foo::foo(const foo&)'
3 | class foo
| ^~~
t.cpp:3:7: note: conversion of argument 1 would be ill-formed:
t.cpp:3:7: note: candidate: 'constexpr foo::foo(foo&&)'
t.cpp:3:7: note: conversion of argument 1 would be ill-formed:
std::array
没有(任何)显式声明的构造函数,因此,它没有来自初始化列表的构造函数,因此您不能只将初始化列表转发到数组。
作为解决方法,您可以使用可变参数模板构造函数
template <typename ... Args>
foo(Args && ... args) : foo(std::array<int, 5>({args ...}))
我认为您正在寻找这种语法:
Foo(const int(&values)[5])
完整示例,
#include <array>
#include <algorithm>
#include <iostream>
class Foo
{
public:
Foo(const int(&values)[5])
{
std::copy(std::begin(values), std::end(values), std::begin(m_values));
}
const auto& values() const noexcept
{
return m_values;
}
private:
std::array<int, 5> m_values;
};
int main()
{
Foo foo({ 1,2,3,4,5 });
for (const auto& value : foo.values())
{
std::cout << value << " ";
}
return 0;
}
我有一个 class,它在构造函数中接收一个 std::array
。对于我的生活,我无法从 std::initializer_list
中编写正确且简单的委托 - 只有我已经注释掉的笨拙的 lambda。谁能告诉我一个没有临时代码的干净合理的方法?
#include <array>
class foo
{
std::array<int,5> t_;
public:
foo(): foo{{}}
{ }
foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
// foo { [il]() {
// std::array<int,5> tmp;
// std::size_t i = 0;
// for (auto ile: il)
// if (i >= tmp.size()) break;
// else tmp[i++]=ile;
// return tmp;
// }()}
{ }
foo(std::array<int,5> t): t_(t)
{ }
};
这给出:
g++ -std=c++17 -pedantic -Wall -Wextra -c -o t.o t.cpp
t.cpp: In constructor 'foo::foo(std::initializer_list<int>)':
t.cpp:12:69: error: no matching function for call to 'std::array<int, 5>::array(std::initializer_list<int>&)'
12 | foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
| ^
In file included from t.cpp:1:
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate: 'std::array<int, 5>::array()'
94 | struct array
| ^~~~~
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate expects 0 arguments, 1 provided
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate: 'constexpr std::array<int, 5>::array(const std::array<int, 5>&)'
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: no known conversion for argument 1 from 'std::initializer_list<int>' to 'const std::array<int, 5>&'
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: candidate: 'constexpr std::array<int, 5>::array(std::array<int, 5>&&)'
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/array:94:12: note: no known conversion for argument 1 from 'std::initializer_list<int>' to 'std::array<int, 5>&&'
t.cpp:12:71: error: no matching function for call to 'foo::foo(<brace-enclosed initializer list>)'
12 | foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
| ^
t.cpp:23:3: note: candidate: 'foo::foo(std::array<int, 5>)'
23 | foo(std::array<int,5> t): t_(t)
| ^~~
t.cpp:23:3: note: conversion of argument 1 would be ill-formed:
t.cpp:12:3: note: candidate: 'foo::foo(std::initializer_list<int>)'
12 | foo(std::initializer_list<int> il = {}): foo{ std::array<int,5>(il) }
| ^~~
t.cpp:12:3: note: conversion of argument 1 would be ill-formed:
t.cpp:9:3: note: candidate: 'foo::foo()'
9 | foo(): foo{{}}
| ^~~
t.cpp:9:3: note: candidate expects 0 arguments, 1 provided
t.cpp:3:7: note: candidate: 'constexpr foo::foo(const foo&)'
3 | class foo
| ^~~
t.cpp:3:7: note: conversion of argument 1 would be ill-formed:
t.cpp:3:7: note: candidate: 'constexpr foo::foo(foo&&)'
t.cpp:3:7: note: conversion of argument 1 would be ill-formed:
std::array
没有(任何)显式声明的构造函数,因此,它没有来自初始化列表的构造函数,因此您不能只将初始化列表转发到数组。
作为解决方法,您可以使用可变参数模板构造函数
template <typename ... Args>
foo(Args && ... args) : foo(std::array<int, 5>({args ...}))
我认为您正在寻找这种语法:
Foo(const int(&values)[5])
完整示例,
#include <array>
#include <algorithm>
#include <iostream>
class Foo
{
public:
Foo(const int(&values)[5])
{
std::copy(std::begin(values), std::end(values), std::begin(m_values));
}
const auto& values() const noexcept
{
return m_values;
}
private:
std::array<int, 5> m_values;
};
int main()
{
Foo foo({ 1,2,3,4,5 });
for (const auto& value : foo.values())
{
std::cout << value << " ";
}
return 0;
}