I have the piece of code hereunder which gives me the following errors:
test.cpp:15:38: error: could not convert ‘std::ref<boost::asio::io_context>(((container*)this)->container::ioCtxt)’ from ‘std::reference_wrapper<boost::asio::io_context>’ to ‘A’
15 | std::array<A,2> bObjs = {std::ref(this->ioCtxt), nullptr};
| ~~~~~~~~^~~~~~~~~~~~~~
| |
| std::reference_wrapper<boost::asio::io_context>
test.cpp:15:61: error: could not convert ‘nullptr’ from ‘std::nullptr_t’ to ‘A’
15 | std::array<A,2> bObjs = {std::ref(this->ioCtxt), nullptr};
| ^
| |
|
This is the minimal piece of code which creates the error in question. This minimal piece of code is a simplistic representation of a more complex situation.
#include <boost/asio.hpp>
struct A
{
boost::asio::ip::tcp::socket sock;
A(boost::asio::io_context& ioCtxtFromContainer): sock(ioCtxtFromContainer){}
};
struct container
{
boost::asio::io_service ioCtxt;
std::array<A,2> bObjs = {std::ref(this->ioCtxt), nullptr};
};
int main(void)
{
container containerObj;
return 0;
}
What is the correct way of passing a reference to A's constructor? Using vectors or an other form of dynamic memory allocation is not allowed/possible here.
CodePudding user response:
- Conmpiler can't do implicit conversion via initializer list:
#include <functional>
#include <array>
struct from{};
struct a
{
a(from&){}
};
int main()
{
from arg{};
// std::array<a, 1> ar{std::ref(arg)}; // can't deduce from initializer list
std::array<a, 1> ar{ arg }; // alright
std::array<a, 1> ar2{ a(arg) }; // also alright
}
- How do you expect to initialize from a Pointer something, that takes a reference?
A(boost::asio::io_context& ioCtxtFromContainer):
You store an array of objects, not an array of pointers. So, either provide a constructor for A
which takes a pointer (which is not what you pbviously want), or have an array of pointers: std::array<A*, 2>
(using smart pointers preferrably).
Or you can use std::optional
, like alanger has suggested.
You can wrapp your initializer list for your array with a variadic template:
template <typename ... Args>
std::array<a, sizeof...(Args)> init_array(Args &&... args)
{
return {a(std::forward<Args>(args))...};
}
from arg{};
auto ar3 = init_array(arg, std::ref(arg)); // works
CodePudding user response:
Store array of optionals if you need explicitly empty fields.
#include <iostream>
#include <optional>
#include <array>
auto main() -> int
{
std::array<std::optional<double>, 3> x {3.2, std::nullopt, 5.0};
return 0;
}
EDIT: or pre-C 17
#include <iostream>
#include <array>
#include <boost/asio.hpp>
#include <boost/optional.hpp>
struct A
{
boost::asio::ip::tcp::socket sock;
A(boost::asio::io_context& ioCtxtFromContainer): sock(ioCtxtFromContainer){}
};
struct container
{
boost::asio::io_service ioCtxt;
std::array<boost::optional<A>,2> bObjs = {
A{this->ioCtxt}, boost::none};
};
auto main() -> int
{
container containerObj;
return 0;
}