These are chat archives for rust-lang/rust

4th
May 2016
LeonineKing1199
@LeonineKing1199
May 04 2016 15:06

So I was checking out rustbyexample and with my limited experience, it seems like Rust is a cross between C++, JavaScript and Haskell.

Edit: The destructuring and tuple stuff seemed pretty neat. I also like the way strings are printed out. The type deduction is also incredibly smart.

Edit edit: Tuples are such a hassle in C++. It's nice to see a language where it's significantly easier to do.

LeonineKing1199
@LeonineKing1199
May 04 2016 15:19
There's only one problem I have with Rust and that's stack vs heap control. In all the examples I saw, there didn't seem to be anything explicit about something living on the stack vs living on the heap. Am I wrong about this?
Stack vs heap control is something that I deem important.
Zakarum
@omni-viral
May 04 2016 15:23
@LeonineKing1199 everything on stack by default
Box, Rc and Arc store wrapped values in heap
types from collections (Vec and friends) store elements in heap of course
there is box keyword
LeonineKing1199
@LeonineKing1199
May 04 2016 15:25
Okay, not bad. Can I allocate raw memory on the heap or is this just not that kind of language?
Zakarum
@omni-viral
May 04 2016 15:25
You can
LeonineKing1199
@LeonineKing1199
May 04 2016 15:25
Also, can I design my own stack-based containers?
Zakarum
@omni-viral
May 04 2016 15:26
Yes again
LeonineKing1199
@LeonineKing1199
May 04 2016 15:26
Neat. I'm really trying to figure out what I can/can't do in this language
Zakarum
@omni-viral
May 04 2016 15:26
You can do such magic in unsafe blocks with pointers and everything
Like in plain C
Erik Hedvall
@Ogeon
May 04 2016 15:27
There's usually no need to handle raw stack memory, unless you are doing something particularly low level. You'll get very far with Vec and Box.
LeonineKing1199
@LeonineKing1199
May 04 2016 15:29
I'm assuming Vec is a contiguous allocation on the heap and Box is a contiguous allocation on the stack?
Erik Hedvall
@Ogeon
May 04 2016 15:30
Vec is analogous to vector in C++, so basically an array list, and box is analogous to owned_ptr, so basically just a heap pointer that frees itself.
Note: my C++ knowledge isn't good, so I may be wrong on the details
LeonineKing1199
@LeonineKing1199
May 04 2016 15:32
Nope, what you said translated perfectly :)
Erik Hedvall
@Ogeon
May 04 2016 15:35
Oh, and I meant to write "raw heap memory" before.
Zakarum
@omni-viral
May 04 2016 15:37
Box<T> is analogous to C++'s std::unique_ptr<T>
Arc<T> is analogous to std::shared_ptr<T>
Rc<T> is Arc<T> but only for single thread to use
Arc<T> and Rc<T> forbid from mutate internal value. So to be more precise Arc<UnsafeCell<T>> is std::shared_ptr<T> actually )
LeonineKing1199
@LeonineKing1199
May 04 2016 15:39
Oh jeez
Zakarum
@omni-viral
May 04 2016 15:40
That is because std::shared_ptr is so unsafe
In Rust you play safely
LeonineKing1199
@LeonineKing1199
May 04 2016 15:40
And I think that's just because you can re-assign it
Zakarum
@omni-viral
May 04 2016 15:41
What do you mean?
LeonineKing1199
@LeonineKing1199
May 04 2016 15:41
Granted, I've never used std::shared_ptr, so far just std::unique_ptr
You can re-assign shared_ptr to other shared_ptr. Is that what you meant by unsafe?
Zakarum
@omni-viral
May 04 2016 15:42
you can call std::shared_ptr::get and get mutable pointer in eleven different places simultaneously
And worst of all is that you can make new std::shared_ptr from raw pointer borrowed from another std::shared_ptr and get double delete
LeonineKing1199
@LeonineKing1199
May 04 2016 15:44
Just looking at this, get() is const-qualified which means it doesn't mutate the stored value
Though yes, you can indeed extract the raw pointer and instantiate any type of smart pointer with it. Which is a weird thing to do lol.
Zakarum
@omni-viral
May 04 2016 15:45
get() does not modify std::shared_ptr itself. Nothing stop you to modify strored value
LeonineKing1199
@LeonineKing1199
May 04 2016 15:45
You mean the dereference of the pointer?
Zakarum
@omni-viral
May 04 2016 15:45
that what you do in C++ usually )
LeonineKing1199
@LeonineKing1199
May 04 2016 15:46
If you're abusing smart pointers like that, you deserve what you get!
Zakarum
@omni-viral
May 04 2016 15:47

consider simple code

void foo(std::shared_ptr<SomeType> const& ptr) {
    ptr->some_method();
}

Is it safe ?
What if some_method modify internal value?
What if two threads executing foo in parallel?

You can never tell by looking at this function alone
You should be careful to not fall in all those pits
LeonineKing1199
@LeonineKing1199
May 04 2016 15:48
Well in that case, some_method would only be called it it's const qualified because ptr itself is.
Zakarum
@omni-viral
May 04 2016 15:49
Nope
LeonineKing1199
@LeonineKing1199
May 04 2016 15:49
You're right, the operator -> gets called first
And that returns T*
That's mutable. Which is fine. You shouldn't be passing a smart pointer then. You should be passing T const*
If ownership isn't relevant, neither are smart pointers.
That's why I don't really use shared_ptr, because more often than not all I need is a unique_ptr and the raw pointer underneath.
Zakarum
@omni-viral
May 04 2016 15:51
Sometimes you just have to share data
And you can't share uniqure_ptr
LeonineKing1199
@LeonineKing1199
May 04 2016 15:51
Only when you need the lifetimes of the object to extend beyond the scope in which it was created.
Zakarum
@omni-viral
May 04 2016 15:51
And you have even more problems if you share raw pointers
LeonineKing1199
@LeonineKing1199
May 04 2016 15:51
Actually, unique_ptr can be move'd around
Zakarum
@omni-viral
May 04 2016 15:51
moved. Not shared. Between threads for example
LeonineKing1199
@LeonineKing1199
May 04 2016 15:51
But with raw pointers you can const-qualify them as you need.
Threads shouldn't be sharing the same smart pointer, each one should just use a copy of the address and leave the management of its lifetime to something else.
Zakarum
@omni-viral
May 04 2016 15:53
"copy of address"... that sounds like another pointer
LeonineKing1199
@LeonineKing1199
May 04 2016 15:53
It is.
Zakarum
@omni-viral
May 04 2016 15:53
So you have pointer to pointer
LeonineKing1199
@LeonineKing1199
May 04 2016 15:54
No, no, you simply pass the pointer by value to your thread when you spawn it.
Zakarum
@omni-viral
May 04 2016 15:54
how this help you with problems of pointers?
LeonineKing1199
@LeonineKing1199
May 04 2016 15:54
With normal RAII interfaces and exception handling, memory management should be lower on your list of problems and bugs.
Zakarum
@omni-viral
May 04 2016 15:56
I think you just get used to all those problems on so deep level that you take them as granted and don't see as problems anymore ))
Of course there is methods to avoid them all
Methods we all use when we write in C and C++
That is why our programs have less bugs than they could have
RAII in C++ help as to not forget to free resources.
Strict type system, borrow checker and other features in Rust can help you do even better
LeonineKing1199
@LeonineKing1199
May 04 2016 16:01

I'm enjoying this discussion. I'm growing to like Rust more. But I learned how to program from cboard.cprogramming.com which is full of nothing but crumudgeons who fundamentally altered me into an old man programmer.

To me, it seems like Rust doesn't offer as much to one if they're already a somewhat competent C++ programmer. A lot of those "safety" features, aren't as attractive to someone who already knows how to manage their memory and thread safety.

But the things like tuple and destructuring support are incredibly attractive.

Plus, the type deduction in Rust seems stronger. No auto keyword littered everywhere, nor decltype()
It's nice.
Daniel Collin
@emoon
May 04 2016 16:02
let is pretty much auto though.
Lifetime and borrowing is concepts not in C++ which are very powerful
LeonineKing1199
@LeonineKing1199
May 04 2016 16:02
That is true.
Daniel Collin
@emoon
May 04 2016 16:02
and Traits are great as well
LeonineKing1199
@LeonineKing1199
May 04 2016 16:03
There is lifetime and borrowing in C++ though. Constructors, destructors and move semantics.
The traits system is also fully-fleshed out as well.
Daniel Collin
@emoon
May 04 2016 16:04
lifetime and borrowing in Rust is quite different from C++
LeonineKing1199
@LeonineKing1199
May 04 2016 16:04
In the sense that things don't die when they unwind from the stack?
Daniel Collin
@emoon
May 04 2016 16:07
No, there are lots of articles written about it. Google on the subject
Peter Atashian
@retep998
May 04 2016 16:08
Lifetimes are how Rust guarantees at compile time that a pointer won't outlive the thing it points to
with no runtime overhead
Instead of having to write flawless C++ code that doesn't have any use after free bugs, you can just write Rust and have the compiler catch those mistakes and yell at you instead
Daniel Collin
@emoon
May 04 2016 16:10
And yell it will :)
Zakarum
@omni-viral
May 04 2016 16:10
A lot
Peter Atashian
@retep998
May 04 2016 16:10
Rust only yells at you because it loves you and cares for you
Zakarum
@omni-viral
May 04 2016 16:11
Sometimes because you just forget to put T: 'a in where clauses )
LeonineKing1199
@LeonineKing1199
May 04 2016 16:11
That would've been a convenient feature if I wasn't already so well-versed in C++.

Also, I read this: http://conscientiousprogrammer.com/blog/2014/12/21/how-to-think-about-rust-ownership-versus-c-plus-plus-unique-ptr/

And lol at using a move'd variable. You get what you get!

Peter Atashian
@retep998
May 04 2016 16:11
For any sufficiently complex C++ project, those mistakes will happen, even with excellent programmers
LeonineKing1199
@LeonineKing1199
May 04 2016 16:12
And that's fine. No program is ever perfect. That's why we write tests. Rust isn't perfect either. Write tests. Catch bugs.
Zakarum
@omni-viral
May 04 2016 16:13
In C++ there is no true move semantics. && does not make you object moved
Daniel Collin
@emoon
May 04 2016 16:13
Also to think that "write tests, catch bugs" will find all your issues is a bit naive.
Zakarum
@omni-viral
May 04 2016 16:14
People just agreed to not use "moved" object anymore.
And destructor will be called
Daniel Collin
@emoon
May 04 2016 16:14
Then thing that Rust catches way more stuff than C++ at compile time is very nice.
Zakarum
@omni-viral
May 04 2016 16:15
And you have to make room to mark object as moved
Daniel Collin
@emoon
May 04 2016 16:16
Also Rust is more strict than C++ (very few implicit casts) which catches bugs also.
Zakarum
@omni-viral
May 04 2016 16:18
And I like traits way more then interfaces
Daniel Collin
@emoon
May 04 2016 16:20
+1
LeonineKing1199
@LeonineKing1199
May 04 2016 16:24

In C++ there is no true move semantics. && does not make you object moved

You're right and wrong. You can't always move objects. You can attempt to which is fine, that's std::forward is for. You just need to understand the reference collapsing rules.

Also to think that "write tests, catch bugs" will find all your issues is a bit naive.

I never implied that it would.

Daniel Collin
@emoon
May 04 2016 16:26
http://is.gd/h2bQg5 - simple example to show how borrowing prevents bugs.
If this was rewritten in C++ there would be no complains
LeonineKing1199
@LeonineKing1199
May 04 2016 16:31

Ah, I see. Rust catches you should you ever decide to program without thinking.

Which is a fine thing, especially when working in teams where newcomers may be unfamiliar with the codebase or just new to the language in general. Perhaps Rust is best placed in the industry where it can better withstand the onslaught of mish-mashed code and a lack of understanding.

Actually, that code might work in C++ because primitives are moved by value.
Peter Atashian
@retep998
May 04 2016 16:32
Even with programmers that understand C++ very well, it can be hard to keep track of absolutely everything all the time 100% perfectly for sufficiently complex projects
and it just takes one mistake to slip through and lead to a major security vulnerability sometime in the indefinite future
Daniel Collin
@emoon
May 04 2016 16:33
This is a very simple example, it gets much harder in larger codebases to spot errors like these.
Our code-base at work is like 4+ milion lines of code or something and it's impossible to keep track of everything.
@LeonineKing1199 no, it wont work.. because you are writing to the struct in the code.
you are taking two pointers to data within the struct
once again a simple example
LeonineKing1199
@LeonineKing1199
May 04 2016 16:40

The fact that your codebase is 4 million lines is honestly irrelevant or it shows foolhardiness. 4 million lines or just 100, write modular code. If you can't write your code in an isolated context then it's not C++'s fault that good practices were not enforced. If you can't write something in its own context and test it then Idk what else to say.

And I guess that example shows how, yes, Rust will catch terrible code written without though before C++ will.

If writing anything involves all 4 million lines then I think your codebase is wrong.
Daniel Collin
@emoon
May 04 2016 16:41
That all sounds nice in theory
practice it's different. You may not have a codebase written in a prefect way
that you have to work with.
LeonineKing1199
@LeonineKing1199
May 04 2016 16:42
Which is unfortunate. But keep in mind, Facebook was written in PHP.
Daniel Collin
@emoon
May 04 2016 16:43
Rust will catch more errors than that. This was (like I wrote) a simple example.
LeonineKing1199
@LeonineKing1199
May 04 2016 17:05
Lol sorry for blowing up the gitter XD
Zakarum
@omni-viral
May 04 2016 17:51
@LeonineKing1199 I'm sure I wasn't wrong when I said that there is no true move semantics in C++. Because C++ "move" involve constructor. Arbitrary code can be executed to "move" value in C++. C++ "move" just pretend to move objects )
I like C++ have at least that, because I have to work with C++03 right now. Without all good stuff like rvalue references and lambdas from C++0x
LeonineKing1199
@LeonineKing1199
May 04 2016 17:53
For any type, there's either a move constructor or a move assignment operator.
Zakarum
@omni-viral
May 04 2016 17:53
Or both
And both can do anything
Even not move value
LeonineKing1199
@LeonineKing1199
May 04 2016 17:53
For user-defined types that is true
Zakarum
@omni-viral
May 04 2016 17:53
You can't go far without user-defined types )
Or C++ will become ASM
LeonineKing1199
@LeonineKing1199
May 04 2016 17:57
You can give your classes move constructors and move assignment operators.
Zakarum
@omni-viral
May 04 2016 17:58
You can't implement them as memmove
As they should be
Because new object is created via move-constructor
And old one still exists
I'm note sure compiler can successfully eliminate many moves of single value if that value handle some resources
Rust's move leave much more room for optimization
LeonineKing1199
@LeonineKing1199
May 04 2016 18:04
Do you mean this which just seems to copy bytes?
Zakarum
@omni-viral
May 04 2016 18:04
@LeonineKing1199 that's how Rust's move implemented internally
LeonineKing1199
@LeonineKing1199
May 04 2016 18:05
So it just copies byes?
Zakarum
@omni-viral
May 04 2016 18:05
Yeap
LeonineKing1199
@LeonineKing1199
May 04 2016 18:06
That sounds logically equivalent to me.
Zakarum
@omni-viral
May 04 2016 18:06
But old value cease to exist on language level
You still can access those bytes via unsafe code. But can't do it without raw pointers.
And destructor wouldn't be called for moved out value
And compiler know's what "move" mean. So it can optimize more aggressevly
LeonineKing1199
@LeonineKing1199
May 04 2016 18:09
That almost sounds like an implementation-level detail though. Compilers are implementation of a specification of a language. As long as it adheres to the standards of the language, it's free to do as it will.
Zakarum
@omni-viral
May 04 2016 18:11
I just try to explain the difference between approaches to "move" in Rust and C++
Basic operation in Rust vs arbitrary code in C++
Moving single object and creating new one
LeonineKing1199
@LeonineKing1199
May 04 2016 18:16

This is bad C++:

std::string str1{"I love programming!"};
std::string str2{"I also love programming!"};

str2 = std::move(str1);

Better:

std::string str1{"I love programming!"};
std::string str2{std::move(str1)};

Probably the "best":

// std::move may be optional depending on return value optimization
std::string str2{std::move(result_of_function_call())};

Now, my understanding of move semantics isn't perfect so if there's a correction to be made in my code, remember, I'm a sensitive young man :)

Zakarum
@omni-viral
May 04 2016 18:20
How you implement it.
C++
class WowString {
    WowString(WowString&& rhs):
        : pointer_(rhs.pointer_)
        , allocator_(std::move(rhs.allocator_))
    {
        // don't forget to clear old one
        rhs.pointer_ = nullptr;
    }

    ~WowString() {
        if (pointer_) // need to check for nullptr everywhere
              allocator_.destroy(pointer_);
    }
}
Rust
// It's already implemented
LeonineKing1199
@LeonineKing1199
May 04 2016 18:25
Oh. So it just does the same thing.
I will say this though, +1 for making your string allocator aware :)
Omg, but what if your allocator isn't move-able though? This is why we use std::forward!!!!
Zakarum
@omni-viral
May 04 2016 18:26
Almost the same. Except Rust do not create new object
not. That is not what std::forward for
You use std::forwardwhen you have T&&
LeonineKing1199
@LeonineKing1199
May 04 2016 18:27
Allocator may not have a move constructor though
Zakarum
@omni-viral
May 04 2016 18:27
Because T&& could be actually Y const&
LeonineKing1199
@LeonineKing1199
May 04 2016 18:28
std::move doesn't automatically yield T&&, it attempts to
Zakarum
@omni-viral
May 04 2016 18:28
std::move yields T&&
for whatever you pass in
look at declarations
std::forward can yield whatever T&& was actually. And I have no idea why Type&& become Type& when you use it
But that how C++ works
I strongly advise you to use std::move when you need to get rvalue reference. And use std::forward when you want to forward T&& arguments without loosing possibly "rvalue" of the reference
In my example. If alloc_ does not have move-constructor the copy-constructor will be called instead
Zakarum
@omni-viral
May 04 2016 18:33
cause rvalue-reference can be implicitly converted to lvalue and const reference
Zakarum
@omni-viral
May 04 2016 18:44
If I try to put all pros of Rust I know
  1. Safety. You can write safe code in C++. You can't write unsafe code in Rust outside of unsafe block.
  2. Modules. C++17 was promised to have them. But no.
  3. Generics. Like concepts for C++. Allow to use static polymorphism everywhere
  4. true move semantics
  5. Checked borrowing with lifetimes
  6. Send requirements for transferring objects between threads
LeonineKing1199
@LeonineKing1199
May 04 2016 18:45

std::move doesn't actually seem to do all that much.

#include <iostream>
#include <string>

using namespace std;

int main()
{
  std::string str{"hello, world"};
  std::string str2{std::move((std::string const& ) str)};
  std::cout << str << std::endl;
  std::cout << str2 << std::endl;
   return 0;
}

Output:

sh-4.3$ g++ -std=c++11 -o main *.cpp                                                                                                                                                           
sh-4.3$ main                                                                                                                                                                                   
hello, world                                                                                                                                                                                   
hello, world
And the "true move semantics" in Rust seem most similar to actually being compiler optimizations that people are freaking out over
Zakarum
@omni-viral
May 04 2016 18:46
std::move((std::string const& ) str) yields std::string const&
because you add const there
but std::move((std::string&)str) yields std::string &&
and std::forward<std::string&>(str) yields std::string&
std::move<std::string&>(str) the same yields std::string&&
Only const stop std::move from yield rvalure reference
LeonineKing1199
@LeonineKing1199
May 04 2016 18:50
Yeah, move'ing doesn't actually move in an absolute sense.
LeonineKing1199
@LeonineKing1199
May 04 2016 18:55

But yeah, my bad, you wouldn't use std::forward. That's horribly wrong. Oh no, I was wrong!

Anyway, so you'd still have to define move and copy constructors which need not be implemented in terms of std::forward either. So that was my mistake. My bad.

But by "true move semantics", it more or less just sounds like you're not actually transferring ownership, the compiler is just intelligently writing your code for you. Which is fine. But I don't think its move semantics are any more true than C++'s.

mhsjlw
@mhsjlw
May 04 2016 19:04
The project I'm working on by the way : https://github.com/mhsjlw/rust-classic
it follows the protocol described here : http://wiki.vg/Classic_Protocol
Peter Atashian
@retep998
May 04 2016 19:12
@LeonineKing1199 Move semantics in Rust are guaranteed for all types with fixed semantics. You never ever have to worry about what the move actually does internally, and the original is always voided. When you "move" a thing in C++, the original will still exist and have to be destructed. When you move something in Rust the original no longer exists, and there is nothing to drop.
C++ destructors sometimes have to be special cased for cases where the type has been moved from. Rust destructors don't need to worry about that case ever.
Zakarum
@omni-viral
May 04 2016 20:00
@LeonineKing1199 One more thing to hate in C++. Copy and move constructors are ordinary constructors. And you can't define constructor with form template<typename T> YourType(T&& arg) : inner_(std::forward<T>(arg)) {} AND move/copy constructor
Because of collision
While Rust have completely distinguishable Clone trait to define copying of objects
Zakarum
@omni-viral
May 04 2016 20:08
@mhsjlw And what is the final grand purpose of it?
mhsjlw
@mhsjlw
May 04 2016 20:09
to learn rust ;)
I like doing networked projects for learning new languages
and that's a fun toy protocol that is always cool to recreate in new languages
Zakarum
@omni-viral
May 04 2016 20:12
@mhsjlw worthwhile goal
mhsjlw
@mhsjlw
May 04 2016 20:13
yeah, well rust is fun so i'm enjoying this
eventually I think i'm going to write a lua plugin API
LeonineKing1199
@LeonineKing1199
May 04 2016 20:18

@SCareAngel

That looks more like a parameterized than a copy/move constructor me.

To me, a copy constructor is,

my_type(my_type const& other) {
  /* ... */
}
Zakarum
@omni-viral
May 04 2016 20:29
@LeonineKing1199 yeap. It is parameterized constructor
Daniel Collin
@emoon
May 04 2016 20:29
All this C++ just shows how complex it is to get things “right” in C++
Zakarum
@omni-viral
May 04 2016 20:29
which collide with copy constructor
Daniel Collin
@emoon
May 04 2016 20:30
Pretty much what @retep998 said
LeonineKing1199
@LeonineKing1199
May 04 2016 20:31
A parameterized constructor collides with a copy constructor?
Zakarum
@omni-viral
May 04 2016 20:31
yeap
LeonineKing1199
@LeonineKing1199
May 04 2016 20:32
Can you post a more complete example?
If you wouldn't mind.
Zakarum
@omni-viral
May 04 2016 20:32
How compiler would know which one you need?
struct MyType {
    MyType();
    template<typename T> MyType(T&&);
    MyType(MyType const&);
}

void foo() {
    MyType my_type_value;
    MyType copy(my_type_value); // which one?
}
LeonineKing1199
@LeonineKing1199
May 04 2016 20:32
That example is incomplete
Zakarum
@omni-viral
May 04 2016 20:34
template constructor would have same signature when T is MyType const&
So which one will be called here?
LeonineKing1199
@LeonineKing1199
May 04 2016 20:36
Maybe I'm confused but this is working for me:
#include <iostream>

template <typename T>
struct static_vector
{
    T data;
    static_vector(void) = default;
    static_vector(T&& some_rvalue_ref)
     : data{some_rvalue_ref}
    {}

    static_vector(static_vector const& other)
     : data{other.data}
    {}

    void print(void) const
    {
        std::cout << data << std::endl;
    }
};

int main(void)
{
    static_vector<int> vec{1337};
    vec.print();
    return 0;
}
Zakarum
@omni-viral
May 04 2016 20:37
You didn't even try to call copy constructor
This message was deleted
LeonineKing1199
@LeonineKing1199
May 04 2016 20:38
#include <iostream>

template <typename T>
struct static_vector
{
    T data;
    static_vector(void) = default;
    static_vector(T&& some_rvalue_ref)
     : data{some_rvalue_ref}
    {}

    static_vector(static_vector const& other)
     : data{other.data}
    {}

    void print(void) const
    {
        std::cout << data << std::endl;
    }
};

int main(void)
{
    static_vector<int> vec{1337};
    vec.print();
    auto other_vec{vec};
    other_vec.print();
    return 0;
}
Output:
sh-4.3$ g++ -std=c++11 -o main *.cpp                                                                                                                                                            
sh-4.3$ main                                                                                                                                                                                    
1337                                                                                                                                                                                            
1337
Zakarum
@omni-viral
May 04 2016 20:39
And now you should tell my, why copy constructor was chosen
This message was deleted
Oh. I get it )
your example is wrong
not whole type is template
LeonineKing1199
@LeonineKing1199
May 04 2016 20:45
Are you templating the constructor?
Zakarum
@omni-viral
May 04 2016 20:45
Yeap
LeonineKing1199
@LeonineKing1199
May 04 2016 20:45
That sounds wrong to me...
Zakarum
@omni-viral
May 04 2016 20:45
How else you can forward arguments to members?
LeonineKing1199
@LeonineKing1199
May 04 2016 20:47
Hmm... I'm not actually sure what you're trying to do here. You can't use parameter packs in a function where you need to expand the pack
Zakarum
@omni-viral
May 04 2016 20:48
@LeonineKing1199 here is a synthetic example
#include <utility>

struct Inner {
    Inner();
    Inner(Inner const&);
    Inner(Inner&&);
    Inner(std::string const&) = default;
    Inner(std::string &&) = default;
};

struct MyType
{
    MyType();
    template <typename T>
    MyType(T&& arg):
        inner_(std::forward<T>(arg))
    {}
    MyType(MyType const& rhs);


    Inner inner_;
};

int main(void)
{
    MyType value;
    MyType copy(value);
    return 0;
}
Some inner value of type can be constructed in multiple ways
LeonineKing1199
@LeonineKing1199
May 04 2016 20:50
What does the compiler say?
Zakarum
@omni-viral
May 04 2016 20:50
error: no matching function for call to 'Inner::Inner(MyType&)'
inner_(std::forward<T>(arg))
Because template constructor was chosen
LeonineKing1199
@LeonineKing1199
May 04 2016 20:51
What if you got rid of the template and instead passed an instance of Inner?
Also, enable_if!
Use enable_if!!!!
That might help with the deduction because as of now, when the template is called, there's no sort of strong deduction or filtering going on.
Zakarum
@omni-viral
May 04 2016 20:58
Like this?
#include <utility>
#include <string>
#include <type_traits>

struct Inner {
    Inner();
    Inner(Inner const&);
    Inner(Inner&&);
    Inner(std::string const&);
    Inner(std::string &&);
};

struct MyType
{
    MyType();
    template <typename T, typename check = typename std::enable_if<!std::is_same<typename std::remove_reference<T>::type, MyType>::value>::type>
    MyType(T&& arg):
        inner_(std::forward<T>(arg))
    {}
    MyType(MyType const& rhs);


    Inner inner_;
};

int main(void)
{
    MyType value;
    MyType copy(value);
    return 0;
}
That might help.
But...
Daniel Collin
@emoon
May 04 2016 21:00
They should rename C++ to Ugly++ instead.
Zakarum
@omni-viral
May 04 2016 21:02
C++ is powerful language. So powerful that it can't hold and blows to the huge declarations
Not elegant
mhsjlw
@mhsjlw
May 04 2016 21:06
it pisses me off when people write braces like
function
{
  function body
}
why not
function {
  function body
}
LeonineKing1199
@LeonineKing1199
May 04 2016 21:07
Did the enable_if stuff work?
Zakarum
@omni-viral
May 04 2016 21:07
Because we can! @mhsjlw
@LeonineKing1199 it always works
But what the cost
Complete unreadablility
Erik Hedvall
@Ogeon
May 04 2016 21:08
@mhsjlw Different people likes different things. Same for different communities. I like four spaces, you like two :smile:
Zakarum
@omni-viral
May 04 2016 21:08
And this is very simple enable_if
LeonineKing1199
@LeonineKing1199
May 04 2016 21:08
Code was meant to be executed by machines, not read by humans XD
Zakarum
@omni-viral
May 04 2016 21:08
Code was meant to be read by humans
Write in ASM than ))
mhsjlw
@mhsjlw
May 04 2016 21:09
@Ogeon nah I like 4 spaces, it's just because I come from JavaScript.
@SCareAngel oh god asm
when i wrote my first asm hello world for ARM arch it was no joke 23 lines
or 13 ?
can't remember
probably 13
Zakarum
@omni-viral
May 04 2016 21:10
There should be only 2 lines which makes it output "Hello world" and bunch of lines just because they must be there
LeonineKing1199
@LeonineKing1199
May 04 2016 21:12
You might be able to make that use of enable_if more palatable through use of constexpr, maybe. I'm not sure.
Zakarum
@omni-viral
May 04 2016 21:14
@LeonineKing1199 yeah. Let's bring that bazooka to tell that I just want to call ordinary copy constructor
What do you want to prove me here?)
I write in C++ 8 hours per day. Than I go home and rest while writing code in Rust.
LeonineKing1199
@LeonineKing1199
May 04 2016 21:23
Nothin'. I was just trying to get your code to compile.
ingoreti
@ingoreti
May 04 2016 22:09
rust rocks
Zakarum
@omni-viral
May 04 2016 22:09
@LeonineKing1199 I know how to deal with it. But I don't like those ways sometimes.
ingoreti
@ingoreti
May 04 2016 22:09
in rust i trust
rust ain't no bust
rust is lust
rust is just
rust. thrust. rocket rust.
Erik Hedvall
@Ogeon
May 04 2016 22:12
@ingoreti are you brainstorming poetry? :smile:
ingoreti
@ingoreti
May 04 2016 22:12
yeah, also, i'm shitface drunk
cheeeeeeers
LeonineKing1199
@LeonineKing1199
May 04 2016 22:12
Lol
You should program stoned, not drunk.
ingoreti
@ingoreti
May 04 2016 22:12
not a bad idea
let's call that dealer
LeonineKing1199
@LeonineKing1199
May 04 2016 22:13
Stoned programming is pretty great and super fun, I hear.
_>
<_<
Zakarum
@omni-viral
May 04 2016 22:13
He tries to find Ballmer Peak
ingoreti
@ingoreti
May 04 2016 22:13
peakaboo
the borrow checker doesn't like me tonight though
it's being a bitch, really
maybe i should treat it better, bahwhahaha, cheeeeeers
hitin' the sack, have a good one