Theo mềnh biết thì biến kiểu auto được hỗ trợ trong C++11. Biến kiểu auto có thể tự động hiểu mọi kiểu dữ liệu của giá trị khi nó được gán.
VD: auto x = "Day Nhau Hoc"
…
Nhưng ngoài ưu điểm trên thì còn cái gì khác không anh em ?
Theo mềnh biết thì biến kiểu auto được hỗ trợ trong C++11. Biến kiểu auto có thể tự động hiểu mọi kiểu dữ liệu của giá trị khi nó được gán.
VD: auto x = "Day Nhau Hoc"
…
Nhưng ngoài ưu điểm trên thì còn cái gì khác không anh em ?
Sách dạy C++ của mềnh k có nới điều này nên giờ mới biết … Thật là vi diệu
Ưu điểm :
Lợi ích của auto trong C++11 là khá lớn trong việc tăng tốc phát triển ứng dụng. Đôi lúc các kiểu dữ liệu rất to lớn và dài, việc sử dụng “tự động chọn kiểu” như auto sẽ giúp cho code ngắn gọn vì “dù gì cũng phải gõ lại đúng kiểu”, bớt các công việc tay chân, như ví dụ trên ta thấy list::iterator là kiểu dữ liệu gõ khá dài. Ví dụ: Concurrency::task<Platform::Array^> (trích trong một project mẫu của Direct3D Windows Phone 8 với XAML).
Nhược điểm của loại biến này là sự không tường minh trong mã nguồn, gây ra việc khó tra cứu nguồn gốc (kiểu dữ liệu) của một biến.
Trích từ : https://www.stdio.vn/articles/read/54/c11-tu-khoa-auto
Một vấn đề mình gặp phải với kiểu auto khi dùng vòng for duyệt qua một vector.
Đang rất là xoắn não
std::wstring input = L"172.26.3.3";
std::vector<std::wstring> ips = {
L"172.26.3.3",
L"172.26.3.3",
L"172.26.3.3"};
bool exist = false;
for(auto ip:ips){
if(ip==input){
exist=true;
break;
}
}
// kết quả khi thực hiện xong vòng lặp nhiều lần thì vẫn có trường hợp exist = false.
// Nếu thực hiện lặp với index như truyền thống thì nó hoạt động cho kêt quả chính xác.
Nghe hư cấu quá, 2 cái gần như nhau làm sao xảy ra kết quả khác nhau được.
Vả lại tìm x trong y thì xài std::find
chứ tội gì phải viết vòng for thế kia :V
Vừa dính hồi chiều xong, đang chạy bất thình lình lỗi. Thực ra không phải vector wstring mà là một vector đối tượng. Trong đối tượng có 1 trường là wstring và muốn return đối tượng ra.
có thể là do copy ctor có vấn đề, for(auto ip:ips)
thì ip
là 1 copy của ips[i]
nên chỉ khác ips[i]
chỗ này thôi (khác nếu copy ctor có vấn đề). Thử thêm 1 dấu &
for(auto& ip:ips)
để ip
chính là ips[i]
coi còn lỗi ko :V
Vầy mới ổn không có & thì nó copy n lần.
Chưa hết. Để chắc ăn mình cho show 2 thằng wstring của ip và input ra kèm luôn độ dài của 2 wstring.
Kết quả 2 wstring dài bằng nhau và giống y đúc nhau nhưng vẫn không nhảy vào if.
Lạ cái nữa là với vẫn dữ liệu đó thì lần chạy sau (gọi lần sau) có thể nhảy vào if rồi lại bất thình lình ngẫu nhiên không nhảy vào. Đến nhọc.
Mai nếu có thời gian mình quay màn hình cho các bạn xem
À mình chợt nhớ ra. Các phần tử trong ips là tham trị. Đúng là nó sẽ copy ra nhưng dữ liệu copy này nó sẽ bị thu hồi ngay khi thoát for (mình từng đọc được warning nói như vậy).
Có thể lý do vì sao trong for mình gán :
pointer = &ip;
Nhưng khi thoát for kiểm tra lại pointer vẫn = nullptr.
Chứ không phải là không nhảy vào if.
Có thể do ip bị thu hồi nhưng vùng nhớ đó có thể được hoặc chưa đươc cấp phát nên mới sinh ra kết quả khi đúng khi sai.
vậy là ko phải gán exists = true
mà gán pointer = &ip
à? :V
nếu vậy thì đúng là bị lỗi đó rồi, thoát khỏi vòng lặp ip
bị thu hồi nên pointer
trỏ vào vùng nhớ đã bị thu hồi, lúc chạy được lúc chạy ko được đúng triệu chứng rồi :V
mà vector
thì đừng nên reference kiểu pointer như vậy, lỡ có push_back ips
nó thay đổi capacity, nó copy mảng cũ sang mảng mới bự hơn thì mấy cái pointer tới phần tử cũ cũng trỏ vào vùng nhớ đã bị thu hồi, cũng chạy sai như vậy :V Xài 1 cái size_t p
lưu index của phần tử đó rồi gọi ips[p]
thì chắc ăn hơn :V
thứ nhất là thêm & vào: auto&
thứ hai là xài size_t
thay cho pointer, lấy index của ip
trong ips
bằng cách này: std::distance(&ips[0], &ip)
cái đó là cách chữa cháy, còn cách khác xài thư viện <algorithm>
thì thế này:
auto it = std::find(begin(ips), end(ips), input);
size_t index = -1;
if (it != end(ips))
index = std::distance(begin(ips), it);
else
//ko tìm thấy
hoặc xài thẳng it
như con trỏ: *it
luôn ko cần gán cái index
làm gì, nếu sau đó ko có push_back
gì vào ips
nữa :V
có cách Pythonista nữa: http://reedbeta.com/blog/python-like-enumerate-in-cpp17/ thì viết thế này:
for (auto [i, ip] : enumerate(ips))
{
// i là index, ip là ips[i]
}
ko cần auto&
ở đây luôn :V :V :V :V
C++17 phong cách Python :V :V :V
http://coliru.stacked-crooked.com/a/ec5a5b8c34fc9eea
#include <tuple>
#include <vector>
#include <string>
#include <iostream>
template <typename T,
typename TIter = decltype(std::begin(std::declval<T>())),
typename = decltype(std::end(std::declval<T>()))>
constexpr auto enumerate(T&& iterable)
{
struct iterator {
size_t i;
TIter iter;
bool operator!=(const iterator& other) const { return iter != other.iter; }
void operator++() { ++i; ++iter; }
auto operator*() const { return std::tie(i, *iter); }
};
struct iterable_wrapper {
T iterable;
auto begin() { return iterator{ 0, std::begin(iterable) }; }
auto end() { return iterator{ 0, std::end(iterable) }; }
};
return iterable_wrapper{ std::forward<T>(iterable) };
}
int main()
{
std::wstring input = L"172.26.3.3";
std::vector<std::wstring> ips = {
L"172.26.3.1",
L"172.26.3.3",
L"172.26.3.3",
};
size_t index = -1;
for (auto [i, ip] : enumerate(ips))
{
if (ip == input)
{
index = i;
break;
}
}
std::cout << index;
}
Nhiều cái như resize vector đúng là mình chưa ngờ tới. Cảm ơn anh em đã thông não