Error when using std::make_move_iterator to insert a std::list<std::unique_ptr>> into another one - c++11

I've been reading this answer about moving elements from a std::vector<std::unique_ptr<T>> to another one using std::make_move_iterator. It works flawlessly:
std::vector<std::unique_ptr<int>> c1;
std::vector<std::unique_ptr<int>> c2;
c1.push_back(std::unique_ptr<int>(new int));
c2.insert(c2.end(), std::make_move_iterator(c1.begin()), std::make_move_iterator(c1.end()));
Now I tried to change it to use a different container (std::list):
std::list<std::unique_ptr<int>> c1;
std::list<std::unique_ptr<int>> c2;
c1.push_back(std::unique_ptr<int>(new int));
c2.insert(c2.end(), std::make_move_iterator(c1.begin()), std::make_move_iterator(c1.end()));
But compilation fails with:
error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
However, it does work if lists contain other objects (like std::string):
std::list<std::string> s1;
std::list<std::string> s2;
s2.insert(s2.end(), std::make_move_iterator(s1.begin()), std::make_move_iterator(s1.end()));
Now, if I use another answer from the same question, which uses std::back_inserter and std::move, it works with both std::vector and std::list:
std::list<std::unique_ptr<int>> c1;
std::list<std::unique_ptr<int>> c2;
c1.push_back(std::unique_ptr<int>(new int));
std::move(c1.begin(), c1.end(), std::back_inserter(c2));
As far as I understand, this solution basically moves each item individually when back inserting on the second container.
My question is, why using std::make_move_iterator on a std::list of std::unique_ptr doesn't work but it does with std::vector or if the list element is of a different type?
Note: I'm using Visual Studio 2010.

The core problem is that Visual Studio 2010's implementation of std::list::insert doesn't support moving semantics. Internally, the std::list::insert invokes a method called _Insert, which is declared as follows in VS 2010:
void _Insert(const_iterator _Where, const _Ty& _Val)
In VS 2017 (not checked for other versions), it calls the same method but it is declared as:
void _Insert(_Unchecked_const_iterator _Where, _Valty&&... _Val)
As seen, VS 2017 uses an rvalue reference, therefore calling the moving constructor of std::unique_ptr when making the insertion. On the other hand, VS 2010 uses an lvalue reference instead, so at some moment the copy constructor is called, which is declared private for std::unique_ptr, generating the compilation error.
Conclusion
In VS 2010 there is no way to use the solution based on std::make_move_iterator because how std::list::insert is implemented. Options for appending a std::list<std::unique_ptr<T>> into another one include:
Using the back_inserter:
std::move(c1.begin(), c1.end(), std::back_inserter(c2));
Using std::list::splice (credit to #T.C.), which is very useful since it can be directly used with lists returned by functions:
c2.splice(c2.end(), c1);

Related

D / DLang : Inhibiting code generation of module-private inlined functions

I have a D module which I hope contains public and private parts. I have tried using the keywords private and static before function definitions. I have a function that I wish to make externally-callable / public and ideally I would like it to be inlined at the call-site. This function calls other module-internal functions that are intended to be private, i.e. not externally callable. Calls to these are successfully inlined within the module and a lot of the cruft is disposed of by CTFE plus known-constant propagation. However the GDC compiler also generates copies of these internal routines, even though they have been inlined where needed and they are not supposed to be externally callable. I'm compiling with -O3 -frelease. What should I be doing - should I expect this even if I use static and/or private?
I have also taken a brief look at this thread concerning GCC hoping for insight.
As I mentioned earlier, I've tried both using private and static on these internal functions, but I can't seem to suppress the code generation. I could understand this if a debugger needed to have copies of these routines to set breakpoints in. I need to stress that this could perhaps be sorted out somehow at link-time, for all I know. I haven't tried linking the program, I'm just looking at the generated code in the Matt Godbolt D Compiler Explorer using GDC. Everything can be made into templates with a zero-length list of template parameters (e.g. auto my_fn()( in arg_t x ) ), tried that, it doesn't help but does no harm.
A couple of other things to try: I could try and make a static class with private parts, as a way of implementing a package, Ada-style. (Needs to be single-instance strictly.) I've never done any C++, only massive amounts of asm and C professionally. So that would be a learning curve.
The only other thing I can think of is to use nested function definitions, Pascal/Ada-style, move the internal routines to be inside the body of their callers. But that has a whole lot of disadvantages.
Rough example
module junk;
auto my_public_fn() { return my_private_fn(); }
private
static // 'static' and/or 'private', tried both
auto my_private_fn() { xxx ; return whatever; }
I just had a short discussion with Iain about this and implementing this is not as simple as it seems.
First of all static has many meanings in D, but the C meaning of translation unit local function is not one of them ;-)
So marking these functions as private seems intuitive. After all, if you can't access a function from outside of the translation unit and you never leak an address to the function why not remove it? It could be either completely unused or inlined into all callers in this case.
Now here's the catch: We can't know for sure if a function is unused:
private void fooPrivate() {}
/*template*/ void fooPublic()()
{
fooPrivate();
}
When compiling the file GDC knows nothing about the fooPublic template (as templates can only be fully analyzed when instantiated), so fooPrivate appears to be unused. When later using fooPublic in a different file GDC will rely on fooPrivate being already emitted in the original source - after all it's not a template so it's not being emitted into the new module.
There might be workarounds but this whole problem seems nontrivial. We could also introduce a custom gcc.attribute attribute for this. It would cause the same problems with templates, but as it's a specific annotation for one usecase (unlike private) we could rely on the user to do the right thing.

Arguments/Struct compatibility when calling a dynamic library on OSX

I have 2 separate projects on OSX:
-the first is a MachO Dynamic Library project in XCode.
It has a function that is being called with an argument (a struct).
-the second is a Qt application project in Qt Creator.
It loads the dynamic library and calls the function, passing a struct as an argument.
Of course both share the same declaration of that function and struct.
The problem is, when I call the function, the values in the struct received in the function have nothing to do with the values I sent from the application. A simple printf before calling the function and another one within the function shows completely different values.
What did I did wrong?
My struct is composed of the following elements :
-multiple std::string
-multiple int
-multiple char[64]
Thanks!
The problem was an incompatibility with std::string, something about compiler flags/library that change the way std::string are implemented. I just changed everything to char[].

Calling a property on the const reference

I have C++/CLI class that defines a property:
public ref class AbstractOffer
{
public:
AbstractOffer();
property String^ Body;
};
In some function the AbstractOffer class is passed by const ref
foo(const AbstractOffer^ ao)
{
ao->Body;
}
When I call the property the method compiler gives the following error :-
error C2662: 'ivrworx::interop::AbstractOffer::Body::get' : cannot
convert 'this' pointer from 'const ivrworx::interop::AbstractOffer'
to 'ivrworx::interop::AbstractOffer %' 1> Conversion loses
qualifiers
It seems somehow connected to const. How can I call the Body property of the object if the object reference is passed by const?
The const qualifier is a problem in C++/CLI. It is only meaningful when it can be checked and that's not in general possible in .NET. It is of course not a problem when you only have one kind of compiler and that compiler follows strict language rules. Like C++. But .NET supports many languages, your method could be easily called from a Cobol.NET program for example. The odds of ever getting const-correctness added to the Cobol language are zero.
The compiler does compile code with const qualifiers and does make an effort to check when it can. Which is why you got the diagnostic. That can even work when the declaration exists in another assembly, as long as it was compiled with C++/CLI, the compiler emits modopt annotations in the metadata.
But there are limitations with that. Properties are one of them, you can't add the const qualifier to the getter, or a member function in general, you'll get slapped with C3842.
Best thing to do is to use C++/CLI for what it is good at, it is an interop language. And const qualifiers just don't work well in an interop scenario.
The only way I know to get round this is the cast away the const-ness. As long as you don't modify the object, it should be fine. (If you do modify it, I've no idea what the outcome will be).
i.e. change your function to be
void foo(const AbstractOffer^ ao)
{
const_cast<AbstractOffer^>(ao)->Body;
}

How to pass managed reference to unmanaged code in C++/CLI?

I'm using C++/CLI only to unit test unmanaged C++ code in VS2010. I switched the compiler to /clr and using the unmanaged code from a static library.
I have a simple int property in my test class.
I would like to pass that as a const int & to a function in native C++. But it can't compile and I've found out that, it's because you can't mix references like that.
What is the way to do it, I tried to following and it's working, but is there a nicer way?
[TestClass]
public ref class MyTestClass
{
private:
int _my_property;
public:
[TestMethod]
void MyTestMethod()
{
MyNativeClass c;
// c.SomeMethod(_my_property) this doesn't work
int i = _my__property;
c.SomeMethod(i) // this works
}
}
C++ references are really just syntactic sugare for pointers. A C++ pointer points to a specific point in memory, while CLI references can be freely moved around by the garbage collector. To pass a reference to an object in managed memory to unmanged code, you need to pin the pointer.
More info and sample in another SO question: Convert from C++/CLI pointer to native C++ pointer
Edit 2
I'm removing the additional information, since it is obviously wrong (thanks #Tergiver and #DeadMG for your comments). I'm also making the post community wiki, so feel free to add any additional correct information.

Visual Studio 2010 and Test Driven Development

I'm making my first steps in Test Driven Development with Visual Studio. I have some questions regarding how to implement generic classes with VS 2010.
First, let's say I want to implement my own version of an ArrayList.
I start by creating the following test (I'm using in this case MSTest):
[TestMethod]
public void Add_10_Items_Remove_10_Items_Check_Size_Is_Zero() {
var myArrayList = new MyArrayList<int>();
for (int i = 0; i < 10; ++i) {
myArrayList.Add(i);
}
for (int i = 0; i < 10; ++i) {
myArrayList.RemoveAt(0); //should this mean RemoveAt(int) or RemoveAt(T)?
//VS doesn't know. Any work arounds?
}
int expected = 0;
int actual = myArrayList.Size;
Assert.AreEqual(expected, actual);
}
I'm using VS 2010 ability to hit
ctrl + .
and have it implement classes/methods on the go.
I have been getting some trouble when implementing generic classes. For example, when I define an .Add(10) method, VS doesn't know if I intend a generic method(as the class is generic) or an Add(int number) method. Is there any way to differentiate this?
The same can happen with return types. Let's assume I'm implementing a MyStack stack and I want to test if after I push and element and pop it, the stack is still empty. We all know pop should return something, but usually, the code of this test shouldn't care for it. Visual Studio would then think that pop is a void method, which in fact is not what one would want. How to deal with this? For each method, should I start by making tests that are "very specific" such as is obvious the method should return something so I don't get this kind of ambiguity? Even if not using the result, should I have something like int popValue = myStack.Pop() ?
How should I do tests to generic classes? Only test with one generic kind of type? I have been using ints, as they are easy to use, but should I also test with different kinds of objects? How do you usually approach this?
I see there is a popular tool called TestDriven for .NET. With VS 2010 release, is it still useful, or a lot of its features are now part of VS 2010, rendering it kinda useless?
Whenever I define a new property in my test code, and ask VS to generate that method stub for me, it generates both a getter and a setter. If I have something like int val = MyClass.MyProperty i'd like to to understand that (at least yet) I only want to define a getter.
Thanks
I see there is a popular tool called TestDriven for .NET. With VS 2010 release, is it still useful, or a lot of its features are now part of VS 2010, rendering it kinda useless?
It's still useful in case you use one of a number of different unit testing frameworks (nunit, mbunit, xunit, csunit, etc).
There are also other tools (like Visual Nunit) that provide visual studio integration for running unit tests.
To your code sample, why would you have a method RemoveAt(T obj)?
You can do RemoveAt(int index) and Remove(T obj) instead. Take a look at Microsoft's APIs (for example, for List<T>) that see how they set up the Remove methods for a generic collection.
And now for your points:
1: What would Add(int number) do? If I understand your intentions correctly, Add(10) can only be intepreted as "Add value 10 at the end of my collection". If you wanted to add a value at a particular index, you can (and probably should) name that method Insert: Insert(int index, T value).
2: sure, Visual Studio will interpret the method as void at first, but you can edit it to be something like
public class MyStack<T>
{
public T Pop()
{
}
}
The stubs built by pressing Ctrl+. are a convenience, but not gospel. You don't HAVE to always assign a return value to a variable. If you don't need it in a test, don't do it. If you want VS to pick up on a return type other than void, you can write a different unit test (e.g. that Pop() returns the last pushed value).
3: I'd test with the types that I see most frequently used in my code. If you're writing a public API, then test with as many types as possible. If you're using NUnit, look into using the [TestCase] attribute to help you avoid writing some duplicate code.
4: I still use TestDriven, but I haven't tried going without it, so I can't really make a useful comparison.
5: Just delete the setter if you don't need it. Some addon frameworks like ReSharper support more advanced code generation, including read-only properties.

Resources