Getting c++11 auto initialization syntax right - c++11

I am newbie programmer in C++ (but a veteran programmer in other languages) and I am trying to use "Modern C++" in my code.
I am wondering what I am doing wrong here, trying to initialize an istream from a boost::asio::streambuf:
#include <iostream>
#include <boost/asio/streambuf.hpp>
class A {
public:
void foo();
private:
boost::asio::streambuf cmdStreamBuf_{};
};
void A::foo() {
std::istream is1{&cmdStreamBuf_}; // works
auto is2 = std::istream{&cmdStreamBuf_}; // does not compile
}
I get this error:
try.cpp:13:41: error: use of deleted function 'std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)'
I am not trying to copy; I thought I was constructing an std::istream!

Since all the answers were in the comments, I thought I'd finish this off by doing an official answer myself.
I am using a c++ library that doesn't have movable streams, and this matters because
auto is2 = std::istream{&cmdStreamBuf_};
creates a new std::istream and then initializes is2 with that rvalue (temporary object). It initializes it by calling the copy constructor or the move constructor. My c++ library apparently does not have either of these constructors, therefore the call fails.
I had originally thought that
auto varname = typename{...};
was the conceptually the same as
typename varname{...};
but it is not. So, this is an instance where you can't use auto to create a variable.
(sigh) And I was really hyped on using auto everywhere.

Related

Static casting to unique_ptr

I have a head file which needs to hide some internals for complexity and "secrecy" reasons. I've therefore a raw void pointer declared in the oublic header, inside the code there are static casts to convert the raw pointer to it's actual type.
Now due to general memory management changes I need to change the type internally to a unique_ptr (it's coming from an object factory now as a unique_ptr, previously it was a raw pointer).
So in my header I have this:
class SomeClass {
private:
void *_hiddenTypeInstance;
}
Is it possible to static-cast this _hiddenTypeInstance to an internally known unique_ptr type?
This is not a direct answer of what you wanted, but a proposal how to do things nicer:) You can actually still use the memory semantics of std::unique_ptr with hiding the internals and without using the ugly void*. As others have mentioned, you should look into PIMPL, but to summarize:
Forward declare the internal type in the public header
Use std::unique_ptr with that type and provide a dtor for the class which holds that member (otherwise you will get compilation errors because a default dtor will be generated, that will try to delete the forward declared class and will fail to do so).
This would look something like this:
#include <memory>
class CPrivate; // Forward declare the internal class
class CPublic
{
public:
// You need the dtor here, since when you implement it in the .cpp of your library,
// where the definition of CPrivate is known, the dtor of std::unique_ptr will know how to delete it.
// If you do not put the dtor here, a default one will be generated here which invokes the dtor of std::unique_ptr, and here
// since CPrivate is forward declared the dtor of std::unique_ptr will not know how to delete it and you will get an error
~CPublic();
private:
std::unique_ptr<CPrivate> m_pPrivate;
}
By using this, you can then escape the casts inside the implementation from the void* to the actual type.
As for the original question - you can always cast void* to a std::unique_ptr<T>* (a pointer to a unique_ptr). But I would advise to evaluate the solution above. Because the void* thing moves away all type strictness - e.g what happens if someone changes T ?
if i understand you problem in a correct way: here is what you can do. This example is just for understanding of a concept. You can use it in your own code. Since I dont have the entire code I cant write exact solution.
class SomeClass {
private:
void *_hiddenTypeInstance;
public:
std::unique_ptr<int> foo() {
int a;
a = 2;
return std::unique_ptr<int>(&a);
}
void bar() {
std::unique_ptr<int> temp_hidden_type_instance;
temp_hidden_type_instance = std::unique_ptr<int>(static_cast<int*>(_hiddenTypeInstance));
temp_hidden_type_instance = foo();
}
};

std::vector of type deduced from initializers before C++17 ... any workaround for C++11?

I learned that from C++17, with the deduction guides, template arguments of std::vector can be deduced e.g. from the initialization:
std::vector vec = { function_that_calculate_and_return_a_specifically_templated_type() }
However I do not have the luxury of C++17 in the machine where I want to compile and run the code now.
Is there any possible workaround for C++11? If more solutions exist, the best would be the one that keep the readability of the code.
At the moment the only idea that I have is to track the various cases along the code (luckily they should not be too many) and make some explicit typedef/using.
Any suggestion is very welcome
The usual way to use type deduction for class template when CTAD is not available is providing a make_* function template, e.g. for your case (trailing return type is necessary for C++11):
#include <vector>
#include <type_traits>
#include <tuple>
template <class ...Args>
auto make_vec(Args&&... args) ->
std::vector<typename std::decay<typename std::tuple_element<0, std::tuple<Args...>>::type>::type>
{
using First = typename std::decay<typename std::tuple_element<0, std::tuple<Args...>>::type>::type;
return std::vector<First>{std::forward<Args>(args)...};
}
You can invoke the above with
const auto v = make_vec(1, 2, 3);
which gets at least kind of close to CTAD in the sense that you don't have to explicitly specify the vector instantiation.
While the answer by lubgr is a correct way, the following template is simpler and seems to work as well:
#include <vector>
#include <string>
template <typename T>
std::vector<T> make_vec(const std::initializer_list<T> &list)
{
return std::vector<T>(list);
}
int main()
{
auto v = make_vec({1,2,3});
auto v2 = make_vec({std::string("s")});
std::string s("t");
auto v3 = make_vec({s});
return v.size() + v2.size() + v3.size();
}
One advantage of using the initializer_list template directly are more clear error messages if you pass mixed types like in make_vec({1,2,"x"});, because the construction of the invalid initializer list now happens in non-templated code.

When initializing an atomic class member it requires a 'deleted' function, but adding it would make it no longer trivially copyable

When initializing an atomic class member it requires a 'deleted' function, but adding it would make it no longer trivially copyable which is a requirement for an object/struct to be atomic. Am I just not understanding how to do this correctly, or is this a problem in the c++ standard?
Take the example below:
#include <atomic>
#include <cstdint>
template<typename T>
struct A
{
T * data;
std::atomic<uintptr_t> next;
};
template<typename T>
class B
{
std::atomic<A<T>> myA;
public:
B ( A<T> & a ) noexcept
{
myA.store(a, std::memory_order_relaxed );
}
};
int main ()
{
A<int> a;
B<int> b(a);
return 0;
}
Trying to compile this with g++ gives error: use of deleted function 'A<int>::A(const A<int>&)' myA.store(a, std::memory_order_relaxed);. My understanding of this error is that the atomic::store method is looking for that constructor in my struct A but not finding it.
Now here is what happens when I add that constructor:
#include <atomic>
#include <cstdint>
template<typename T>
struct A
{
T * data;
std::atomic<uintptr_t> next;
A(const A<T>& obj) { }
A( ) { }
};
template<typename T>
class B
{
std::atomic<A<T>> myA;
public:
B ( A<T> & a ) noexcept
{
myA.store(a, std::memory_order_relaxed );
}
};
int main ()
{
A<int> a;
B<int> b(a);
return 0;
}
I no longer receive the above compiler error but a new one coming from the requirements of the atomic class required from 'class B<int>' .... error: static assertion failed: std::atomic requires a trivially copyable type ... In other words by adding the used-defined constructors I have made my struct A a non-trivially copyable object which cannot be initialized in class B. However, without the user-defined constructors I cannot use the store method in myA.store(a, std::memory_order_relaxed).
This seems like a flaw in the design of the std::atomic class. Now maybe I am just doing something wrong because I don't have a lot of experience using C++11 and up (I'm old school). Since 11 there have been a lot of changes and the requirements seem to be a lot stricter. I'm hoping someone can tell me how to achieve what I want to achieve.
Also I cannot change std::atomic<A<T>> myA; to std::atomic<A<T>> * myA; (changed to pointer) or std::atomic<A<T>*> myA;. I realize this will compile but it will destroy the fundamental design of a class I am trying to build.
The problem here resides in the fact that std::atomic requires a trivially copiable type. This because trivially copyable types are the only sure types in C++ which can be directly copied by copying their memory contents directly (eg. through std::memcpy). Also non-formerly trivially copyable types could be safe to raw copy but no assumption can be made on this.
This is indeed important for std::atomic since copy on temporary values is made through std::memcpy, see some implementation details for Clang for example.
Now at the same time std::atomic is not copy constructible, and this is for reasonable reasons, check this answer for example, so it's implicitly not trivially copyable (nor any type which contains them).
If, absurdly, you would allow a std::atomic to contain another std::atomic, and the implementation of std::atomic contains a lock, how would you manage copying it atomically? How should it work?

Why does making this virtual destructor inline fix a linker issue?

If I have a pure virtual class InterfaceA that consists solely of a pure virtual destructor, why do I have to define the destructor as inline? I I don't I get an error when I try to link it.
Below is an admittedly contrived example, however it illustrates the point. The point does not compile for me using cmake and g++. However, if I change the InterfaceA destructor definition as follows - inline InterfaceA::~InterfaceA(){}; then it compiles.
Why is this? What does the inline keyword do?
// InterfaceA.h, include guards ommitted for clarity
class InterfaceA
{
public:
virtual ~InterfaceA() = 0;
};
InterfaceA::~InterfaceA(){};
// A.h, include guards ommitted for clarity
#include "InterfaceA.h"
class A : public InterfaceA
{
public:
A(int val)
: myVal(val){};
~A(){};
int myVal;
};
// AUser.h, include guards ommitted for clarity
#include "InterfaceA.h"
class AUser
{
public:
AUser(InterfaceA& anA)
: myA(anA){};
~AUser(){};
int getVal() const;
private:
InterfaceA& myA;
};
// AUser.cpp
#include "AUser.h"
#include "A.h"
int AUser::getVal() const
{
A& anA = static_cast<A&>(myA);
return anA.myVal;
}
// main.cpp
#include "AUser.h"
#include "A.h"
#include <iostream>
int main(){
A anA(1);
AUser user(anA);
std::cout << "value = " << user.getVal() << std::endl;
return 0;
}
You have to use the inline keyword when defining functions in header files. If you do not, and the file is included in more than one translation unit, the function will be defined twice (or more times).
The linker error is probably something like "Symbol ... is multiply defined" right?
If you defined the member function in the body of the class, it would be implicitly inline and it would also work.
See this answer
To answer the question "What does the inline keyword do?":
In the old days it would be used to ask the compiler to inline functions i.e. insert the code whenever the function is used instead of adding a function call. Eventually it turned into a simple suggestion since compiler optimizers became more knowledgeable about which functions were inline candidates. These days it is used almost exclusively to define functions in header files that must have external linkage.
inline means that compiler is allowed to add code directly to where the function was called. It also removes function from external linkage, so both your compile units would have local version of.. pure destructor.
// InterfaceA.h, include guards ommitted for clarity
class InterfaceA
{
public:
virtual ~InterfaceA() = 0;
};
You declare destructor virtual, so compiler almost never would make it inline. Why? because virtual functions are called through vtable - a internal working of virtual functions system, vtable most likely implemented as an array of pointers to member functions. If function is inlined, it would have no address, no legal pointer. If attempt to get address of function is taken, then compiler silently disregards inline keyword. The other effect will be still in place: inlined destructor stops to be visible to linker.
It may look like declaring pure virtual destructor looks like oxymoron , but it isn't. The pure destructor is kind of destructor that would be always called without causing UB. Its presence would make class abstract, but the implicit call in sequence of destructor calls would still happen. If you didn't declare destructor body, it would lead to an UB, e.g. purecall exception on Windows.
If you don't need an abstract base class, then inline definition will suffice:
class InterfaceA
{
public:
virtual ~InterfaceA() {}
};
that is treated by compiler as inline as well, but mixing inline definition and pure member declaration is not allowed.

Is there a way to use Boost serialization on stl functional

I have an stl functional std::function<int(int,int)> fcn_ as a member field of a class. Is there a way to serialize it using boost serialization? If I do the following
template<class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & fcn_;
}
I got the error
/opt/local/include/boost/serialization/access.hpp:118:9: error: 'class std::function<int(int, int)>' has no member named 'serialize'
Is there a header file (say something like<boost/serialization/vector.hpp>) I can include that implements serialize for std::function? Or is there an easy way to implement one myself?
Thanks!
I haven't had a look at how Boost serialization works, but here is a possible approach.
template<typename T>
std::ostream& serialize(std::ostream& out, const std::function<T>& fn)
{
using decay_t = typename std::decay<T>::type;
if(fn.target_type() != typeid(decay_t)) throw std::runtime_error(std::string(typeid(decay_t).name()) + " != " + fn.target_type().name());
const auto ptr = fn.template target<decay_t>();
out << reinterpret_cast<void*>(*ptr);
return out;
}
template<typename T>
std::istream& deserialize(std::istream& in, std::function<T>& fn)
{
using decay_t = typename std::decay<T>::type;
void* ptr = nullptr;
in >> ptr;
fn = reinterpret_cast<decay_t>(ptr);
return in;
}
Please note that this will not work if you are storing lambdas or function objects in your std::functions (as per http://en.cppreference.com/w/cpp/utility/functional/function/target).
A running example can be found coliru.
You could require my_serializable_function<int(int,int)> which knows how to self-describe and reconstruct from such a descriptor.
In other words: you write the code yourself.
Alternatively, you might look at a scripting engine, which already contains stuff like this (Boost Python, several Lua bindings, v8 engine etc.). Though each comes with their own set of trade-offs and might be overkill.
Thanks to Tom and sehe's response. After some research, I realized what I had in mind is not really possible in C++ --- it is generally not possible to serialize an std::function object. By "serialize", I mean being able to transfer (read/write) the object as a byte stream from one program to another program, or to the same program but a different invocation on the same or a different machine. The links below has more discussion about this topic:
Serializing function objects
Can std::function be serialized?

Resources