Câu trả lời:
Sử dụng C ++ 11:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Sử dụng Boost.Assign :
#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;
map<int, char> m = map_list_of (1, 'a') (3, 'b') (5, 'c') (7, 'd');
Cách tốt nhất là sử dụng một chức năng:
#include <map>
using namespace std;
map<int,int> create_map()
{
map<int,int> m;
m[1] = 2;
m[3] = 4;
m[5] = 6;
return m;
}
map<int,int> m = create_map();
extern
các biến sẽ không có giá trị chính xác của chúng trong "trước hàm tạo thời gian chạy chính" này nếu trình biên dịch chỉ nhìn thấy extern
khai báo, nhưng chưa chạy vào định nghĩa biến thực tế .
const map<int,int> m = create_map()
(và do đó, khởi tạo các thành viên const của một lớp trong danh sách khởi tạo:struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
Đây không phải là một vấn đề phức tạp để làm một cái gì đó tương tự để tăng cường. Đây là một lớp chỉ có ba hàm, bao gồm hàm tạo, để sao chép những gì boost đã làm (gần như).
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(const T& key, const U& val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U& val)
{
m_map[key] = val;
return *this;
}
operator std::map<T, U>()
{
return m_map;
}
};
Sử dụng:
std :: map mymap = created_map <int, int> (1,2) (3,4) (5,6);
Đoạn mã trên hoạt động tốt nhất để khởi tạo các biến toàn cục hoặc các thành viên tĩnh của một lớp cần được khởi tạo và bạn không biết khi nào nó được sử dụng trước nhưng bạn muốn đảm bảo rằng các giá trị có sẵn trong nó.
Nếu nói, bạn phải chèn các phần tử vào std :: map ... hiện tại đây là một lớp khác dành cho bạn.
template <typename MapType>
class map_add_values {
private:
MapType mMap;
public:
typedef typename MapType::key_type KeyType;
typedef typename MapType::mapped_type MappedType;
map_add_values(const KeyType& key, const MappedType& val)
{
mMap[key] = val;
}
map_add_values& operator()(const KeyType& key, const MappedType& val) {
mMap[key] = val;
return *this;
}
void to (MapType& map) {
map.insert(mMap.begin(), mMap.end());
}
};
Sử dụng:
typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);
Xem nó hoạt động với GCC 4.7.2 tại đây: http://ideone.com/3uYJiH
############### MỌI THỨ DƯỚI ĐÂY LÀ OBSOLLEX #################
EDIT : map_add_values
Lớp bên dưới, là giải pháp ban đầu tôi đã đề xuất, sẽ thất bại khi nói đến GCC 4.5+. Vui lòng xem mã ở trên để biết cách thêm giá trị vào bản đồ hiện có.
template<typename T, typename U>
class map_add_values
{
private:
std::map<T,U>& m_map;
public:
map_add_values(std::map<T, U>& _map):m_map(_map){}
map_add_values& operator()(const T& _key, const U& _val)
{
m_map[key] = val;
return *this;
}
};
Sử dụng:
std :: map <int, int> my_map; // Sau đó ở đâu đó dọc theo mã map_add_values <int, int> (my_map) (1,2) (3,4) (5,6);
LƯU Ý: Trước đây tôi đã sử dụng một operator []
để thêm các giá trị thực tế. Điều này là không thể như nhận xét của dalle.
##################### KẾT THÚC CỦA PHẦN OBSOLLEX ######################
operator[]
chỉ mất một đối số duy nhất.
error: conflicting declaration ‘map_add_values<int, int> my_map’
error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
Đây là một cách khác sử dụng hàm tạo dữ liệu 2 phần tử. Không có chức năng là cần thiết để khởi tạo nó. Không có mã bên thứ 3 (Boost), không có chức năng hoặc đối tượng tĩnh, không có thủ thuật, chỉ đơn giản là C ++:
#include <map>
#include <string>
typedef std::map<std::string, int> MyMap;
const MyMap::value_type rawData[] = {
MyMap::value_type("hello", 42),
MyMap::value_type("world", 88),
};
const int numElems = sizeof rawData / sizeof rawData[0];
MyMap myMap(rawData, rawData + numElems);
Vì tôi đã viết câu trả lời này nên C ++ 11 đã ra. Bây giờ bạn có thể trực tiếp khởi tạo các thùng chứa STL bằng tính năng danh sách khởi tạo mới:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
Ví dụ:
const std::map<LogLevel, const char*> g_log_levels_dsc =
{
{ LogLevel::Disabled, "[---]" },
{ LogLevel::Info, "[inf]" },
{ LogLevel::Warning, "[wrn]" },
{ LogLevel::Error, "[err]" },
{ LogLevel::Debug, "[dbg]" }
};
Nếu bản đồ là thành viên dữ liệu của một lớp, bạn có thể khởi tạo nó trực tiếp trong tiêu đề theo cách sau (kể từ C ++ 17):
// Example
template<>
class StringConverter<CacheMode> final
{
public:
static auto convert(CacheMode mode) -> const std::string&
{
// validate...
return s_modes.at(mode);
}
private:
static inline const std::map<CacheMode, std::string> s_modes =
{
{ CacheMode::All, "All" },
{ CacheMode::Selective, "Selective" },
{ CacheMode::None, "None" }
// etc
};
};
Tôi sẽ bọc bản đồ bên trong một đối tượng tĩnh và đặt mã khởi tạo bản đồ vào hàm tạo của đối tượng này, bằng cách này, bạn chắc chắn rằng bản đồ được tạo trước khi mã khởi tạo được thực thi.
Chỉ muốn chia sẻ một công việc thuần túy C ++ 98 xung quanh:
#include <map>
std::map<std::string, std::string> aka;
struct akaInit
{
akaInit()
{
aka[ "George" ] = "John";
aka[ "Joe" ] = "Al";
aka[ "Phil" ] = "Sue";
aka[ "Smitty" ] = "Yando";
}
} AkaInit;
Bạn co thể thử:
std::map <int, int> mymap =
{
std::pair <int, int> (1, 1),
std::pair <int, int> (2, 2),
std::pair <int, int> (2, 2)
};
{1, 2}
thay vì std::pair<int, int>(1, 2)
.
Điều này tương tự PierreBdR
, mà không cần sao chép bản đồ.
#include <map>
using namespace std;
bool create_map(map<int,int> &m)
{
m[1] = 2;
m[3] = 4;
m[5] = 6;
return true;
}
static map<int,int> m;
static bool _dummy = create_map (m);
Nếu bạn bị mắc kẹt với C ++ 98 và không muốn sử dụng boost, đây là giải pháp tôi sử dụng khi tôi cần khởi tạo bản đồ tĩnh:
typedef std::pair< int, char > elemPair_t;
elemPair_t elemPairs[] =
{
elemPair_t( 1, 'a'),
elemPair_t( 3, 'b' ),
elemPair_t( 5, 'c' ),
elemPair_t( 7, 'd' )
};
const std::map< int, char > myMap( &elemPairs[ 0 ], &elemPairs[ sizeof( elemPairs ) / sizeof( elemPairs[ 0 ] ) ] );
Bạn có một số câu trả lời rất hay ở đây, nhưng với tôi, nó giống như một trường hợp "khi tất cả những gì bạn biết là một cái búa" ...
Câu trả lời đơn giản nhất về lý do tại sao không có cách chuẩn để khởi tạo bản đồ tĩnh, là không có lý do chính đáng để sử dụng bản đồ tĩnh ...
Bản đồ là một cấu trúc được thiết kế để tra cứu nhanh, gồm một tập hợp các yếu tố không xác định. Nếu bạn biết các yếu tố trước khi sử dụng, chỉ cần sử dụng một mảng C. Nhập các giá trị theo cách được sắp xếp hoặc chạy sắp xếp trên chúng, nếu bạn không thể làm điều này. Sau đó, bạn có thể nhận được hiệu suất log (n) bằng cách sử dụng các hàm stl :: để lặp lại các mục, low_bound / Upper_bound. Khi tôi đã thử nghiệm điều này trước đây, họ thường thực hiện nhanh hơn ít nhất 4 lần so với bản đồ.
Ưu điểm là gấp nhiều lần ... - hiệu suất nhanh hơn (* 4, tôi đã đo trên nhiều loại CPU, nó luôn ở mức 4) - gỡ lỗi đơn giản hơn. Nó chỉ dễ dàng hơn để xem những gì đang xảy ra với một bố cục tuyến tính. - Việc triển khai tầm thường của các hoạt động sao chép, nếu điều đó trở nên cần thiết. - Nó phân bổ không có bộ nhớ trong thời gian chạy, vì vậy sẽ không bao giờ ném ngoại lệ. - Đó là một giao diện chuẩn và rất dễ chia sẻ, DLL hoặc ngôn ngữ, v.v.
Tôi có thể tiếp tục, nhưng nếu bạn muốn nhiều hơn, tại sao không xem nhiều blog của Stroustrup về chủ đề này.
map
cũng là một hình thức hữu ích để biểu diễn một hàm một phần (hàm theo nghĩa toán học; nhưng cũng có thể, theo nghĩa lập trình). Một mảng không làm điều đó. Bạn không thể, giả sử, tra cứu dữ liệu từ một mảng bằng chuỗi.