thảo luận [C++] Thớt bàn luận, hỏi đáp thắc mắc về C++

C++:
  Foo(std::string&& s, int n)
  : name{std::move(s)} // move ctor
  , value{n}
  {

  }

nhưng xài rvalue ref vẫn vướng 1 cách truyền
aVgiONl.png
đó là truyền const lvalue vào:
C++:
const std::string default{"default"};
foos.emplace_back(default, 0); // rvalue ref ko bind vào const lvalue được, báo lỗi
thế là phải viết thêm 1 ctor Foo(const std::string&, int) à? Cái này đụng chạm quy luật DRY dont repeat yourself
Dcnffay.png
C++ rác vậy xao
Dcnffay.png


nhưng ko, truyền copy to the rescue
XgR55w2.gif
XgR55w2.gif
XgR55w2.gif

C++:
Foo(std::string s, int n)
  : name{std::move(s)} // move ctor
  , value{n}
  {

  }
Jjqt3oq.png
Sao không thử universal reference?, 1 ctor là đủ.

https://godbolt.org/z/qonTMzrGv

C++:
#include <cstdio>
#include <utility>
struct A {
    A() = default;
    A(A const &a) { std::puts("copy"); }
    A(A&& a) { std::puts("move"); }
};
struct Foo {
    template <typename T>
    Foo(T &&t, int n) : a{std::forward<T>(t)}, value{n}
    {
    }
    A a;
    int value;
};

int main()
{
    A a;
    const A a2;
    std::fputs("Foo f1{a, 1}: ", stdout);
    Foo f1{a, 1};
    std::fputs("Foo f2{std::move(a), 1}: ", stdout);
    Foo f2{std::move(a), 1};
    std::fputs("Foo f3{A{}, 1}: ", stdout);
    Foo f3(A{}, 1);
    std::fputs("Foo f4{a2, 1}: ", stdout);
    Foo f4{a2, 1};
    std::fputs("Foo f5{std::move(a2), 1}: ", stdout);
    Foo f5{std::move(a2), 1};
    std::fputs("Foo f6{A{a2}, 1}: ", stdout);
    Foo f6{A{a2}, 1};
}

Foo f1{a, 1}: copy
Foo f2{std::move(a), 1}: move
Foo f3{A{}, 1}: move
Foo f4{a2, 1}: copy
Foo f5{std::move(a2), 1}: copy
Foo f6{A{a2}, 1}: copy
move
 
gần 1 năm rồi mới quay lại job c++. Ae cho hỏi đi phỏng vấn job c++ đợt này thường hỏi những gì ạ. em nhớ ngày xưa đi pv toàn hỏi mỗi opp với con trỏ
 
Sao không thử universal reference?, 1 ctor là đủ.

https://godbolt.org/z/qonTMzrGv

C++:
#include <cstdio>
#include <utility>
struct A {
    A() = default;
    A(A const &a) { std::puts("copy"); }
    A(A&& a) { std::puts("move"); }
};
struct Foo {
    template <typename T>
    Foo(T &&t, int n) : a{std::forward<T>(t)}, value{n}
    {
    }
    A a;
    int value;
};

int main()
{
    A a;
    const A a2;
    std::fputs("Foo f1{a, 1}: ", stdout);
    Foo f1{a, 1};
    std::fputs("Foo f2{std::move(a), 1}: ", stdout);
    Foo f2{std::move(a), 1};
    std::fputs("Foo f3{A{}, 1}: ", stdout);
    Foo f3(A{}, 1);
    std::fputs("Foo f4{a2, 1}: ", stdout);
    Foo f4{a2, 1};
    std::fputs("Foo f5{std::move(a2), 1}: ", stdout);
    Foo f5{std::move(a2), 1};
    std::fputs("Foo f6{A{a2}, 1}: ", stdout);
    Foo f6{A{a2}, 1};
}
đụng tới template compile chậm ko cần thiết khi T chỉ là 1 kiểu. Phải bỏ vào header file mà ko bỏ ctor vào cpp file để save vài mili giây compile là chậm ròi
4YMgKo2.gif
 
đụng tới template compile chậm ko cần thiết khi T chỉ là 1 kiểu. Phải bỏ vào header file mà ko bỏ ctor vào cpp file để save vài mili giây compile là chậm ròi
4YMgKo2.gif

Từ khoá: explicit instantiation.

Sent from Xiaomi M2007J20CG using vozFApp
 
Từ khoá: explicit instantiation.

Sent from Xiaomi M2007J20CG using vozFApp
vậy thì mất công ko giấu được implementation của ctor
1xEuo02.gif

à mà viết vậy đâu có cản user xài F{a} tạo copy ko cần thiết đâu. Vậy đâu có khác gì viết thẳng F(A a, int n) luôn
zQU2cJa.png


ý giờ mới biết std::move(const&) được
kH9BFd2.gif
const T&& nó hiểu là const T&
ghXpJrI.png
có trong ví dụ ở cuốn Effective Modern C++ luôn
LTT2cUR.png
thặc phản logic
EB2RUU6.gif
 
vậy thì mất công ko giấu được implementation của ctor
1xEuo02.gif

à mà viết vậy đâu có cản user xài F{a} tạo copy ko cần thiết đâu

ý giờ mới biết std::move(const&) được
kH9BFd2.gif
có trong ví dụ ở cuốn Effective Modern C++ luôn
LTT2cUR.png
thặc phản logic
EB2RUU6.gif

Sao không dấu được nhỉ?
Cứ làm như bình thường thôi, define trong header, implement + explicit instantiation trong cpp.

Sent from Xiaomi M2007J20CG using vozFApp
 
Sao không dấu được nhỉ?
Cứ làm như bình thường thôi, define trong header, implement + explicit instantiation trong cpp.

Sent from Xiaomi M2007J20CG using vozFApp
ghXpJrI.png
à vì chỉ có 1 type nên để luôn trong file cpp cũng được luôn nhỉ
kH9BFd2.gif


vậy còn "lỗi" xài F{a} được thì sao
JiZo9zf.png
đâu có gì khác với viết ctor F(A a) đâu: xài với const lvalue được: tốn 1 copy cần thiết, xài với xvalue prvalue được, nhưng vẫn gặp vấn đề truyền lvalue quên biến nó thành xvalue để bỏ qua 1 copy ko cần thiết

nếu viết F(A&& a) thì truyền lvalue ko được, buộc phải move, tối ưu, và truyền const lvalue ko được, nhưng có thể gọi F{A{a}}, vẫn tốn đúng 1 copy
JEWoIdl.png
à hoặc gọi F{std::move(const_lvalue)} vẫn được nếu kiểu A có copy ctor. Ủa mà gọi F{A{a}}A phải có copy ctor rồi
MjfezZB.png
tóm lại rref thì truyền xvalue prvalue nó move vào hết ko copy, lvalue ko truyền được thì gọi std::move, tệ lắm là mất 1 copy cho const lvalue
JEWoIdl.png
 
Last edited:
gần 1 năm rồi mới quay lại job c++. Ae cho hỏi đi phỏng vấn job c++ đợt này thường hỏi những gì ạ. em nhớ ngày xưa đi pv toàn hỏi mỗi opp với con trỏ
ko đến nỗi gắt như bác kia bảo đâu, hỏi thêm IPC, ít thuật toán nữa. Có ô thích hỏi aligment....
 
Bài C10K quá nổi tiếng rồi, nhưng mà thường kiểu cho bài tập về nhà thôi chứ hỏi tại chỗ ai làm làm kịp được.
Kể cả cho về nhà đi nữa thì bài này tôi thấy không dính dáng gì đến C++ cả vì nó là kiến thức lập trình socket và có thể implement bằng các ngôn ngữ khác, chắc chỉ cho vị trí lập trình hệ thống linux.

Còn 2023 thì nếu tôi phỏng vấn vị trí Senior C++ chắc ngoài leet code ra sẽ hỏi thêm về phần ngôn ngữ: tham chiếu, con trỏ (2 cái này chưa chắc code lâu năm vững), OOP, hàm ảo, STL, vài khái niệm C++ mới như smart pointer, lamda, một vài câu cơ bản về thread, design pattern vậy thôi. Tôi thấy nhiêu đó là đủ base để làm việc rồi. Muốn hỏi đánh đố thì mức lương phải tương ứng chứ.
 
C++ học khó vl, khó ở đây là động đến yếu tố thread, xử lý lỗi, oop nhé, chứ ko phải mấy cái con trỏ , syntax cơ bản, đến cái tài liệu trang chủ đọc tài liệu kỹ thuật chả hiểu mom gì
 
xì mát pon tơ 12 năm rồi mà anh kêu mới hả
t5IcdBZ.gif

thặc đao lòng tính năng ra 12 năm mấy ông dev đéo thèm ngó ngàng
Wf29Rhg.png
Lượng code base còn dùng chuẩn cũ vẫn chiếm nhiều lắm (phần lớn đến từ đống Win32, MFC, embedded) mà không phải công ty nào cũng sẵn lòng move sang chuẩn mới.
 
Lượng code base còn dùng chuẩn cũ vẫn chiếm nhiều lắm (phần lớn đến từ đống Win32, MFC, embedded) mà không phải công ty nào cũng sẵn lòng move sang chuẩn mới.
đao lòng
OANgL56.png
nhiều chỗ chắc còn chưa xài tới C++17 mà ngoảnh đi ngoảnh lại nó đã 6 năm ròi, tính năng 12 năm kia vẫn còn xem là "mới"
WawmAwM.png
 
Lượng code base còn dùng chuẩn cũ vẫn chiếm nhiều lắm (phần lớn đến từ đống Win32, MFC, embedded) mà không phải công ty nào cũng sẵn lòng move sang chuẩn mới.
Cty cũ t làm xài C++03, dùng boost để xài mấy cái mới ở C++11 như smart pointer.
Cty hiện tại thì đang xài C++17, :p
 
Cty cũ t làm xài C++03, dùng boost để xài mấy cái mới ở C++11 như smart pointer.
Cty hiện tại thì đang xài C++17, :p
:adore: công ty cũ cũ dùng c++03, đến tận 2020 chuyển sang công ty cũ mới được dùng c++11. Nghĩ nó đau lòng
 
:adore: công ty cũ cũ dùng c++03, đến tận 2020 chuyển sang công ty cũ mới được dùng c++11. Nghĩ nó đau lòng
T giờ đi pv thì hỏi công ty làm C++ version mấy, nếu xài dưới C++17 là red flag. Vì kinh nghiệm vào mấy công ty này làm thường là maintain đống code cũ, dev cũng không quan tâm đến best practice, expert trong công ty thường là expert về domain, không phải expert về software
 
Back
Top