-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiler error when using custom map type and type alias #428
Comments
This might be a bug, looking into why it isn't choosing your specified constructor |
Just trying to replicate that error. I suspect it is related to the auto deduced mapping and the explicit constructor_t not taking over. I suspect a manual mapping of struct map_builder {
template<typename Iter>
constexpr class_type operator()( Iter first, Iter last ) const {
class_type ans;
// calling distance here can be costly and incur a parse of the range ans.reserve(val.size());
// it may be random when the data is out of order from expected but that just preserves the known size
// alternatively if your map type has an iterators range ctor return class_type( first, last );
for( ; first != last; ++first ) {
auto [k,v] = *first;
ans.emplace(k, v);
}
return ans;
}
}; |
I came up with this simple example to test this issue: template <class Key, class T> class vector_map {
private:
using value_type = std::pair<Key, T>;
using vector_type = std::vector<value_type>;
using iterator = typename vector_type::iterator;
vector_type data_;
public:
vector_map() = default;
template <class... Args> std::pair<iterator, bool> emplace(Args &&...args) {
data_.emplace_back(std::make_pair(std::forward<Args>(args)...));
return std::make_pair(data_.end() - 1, true);
}
};
namespace daw::json {
template <class Key, class T> struct json_data_contract<vector_map<Key, T>> {
using class_type = vector_map<Key, T>;
using map_type = std::unordered_map<Key, T>;
struct map_builder {
template <typename Iter> constexpr class_type operator()(Iter first, Iter last) const {
class_type ans;
for (; first != last; ++first) {
auto [k, v] = *first;
ans.emplace(k, v);
}
return ans;
}
};
using constructor_t = map_builder;
using type = json_type_alias<json_key_value_no_name<map_type, Key, T, map_builder>>;
static inline auto to_json_data(const class_type &val) {
map_type ans;
ans.reserve(val.size());
for (const auto &[k, v] : val) {
ans.emplace(k, v);
}
return ans;
}
};
} // namespace daw::json
void json_test(const std::string &json_file) {
std::ifstream t(json_file);
std::stringstream buffer;
buffer << t.rdbuf();
auto data_source = buffer.str();
std::string_view data_view(data_source.data(), data_source.size());
auto obj = daw::json::from_json<vector_map<std::string, int>>(data_view);
auto obj_json = daw::json::to_json(
obj, daw::json::options::output_flags<daw::json::options::SerializationFormat::Pretty>);
std::cout << obj_json.c_str() << std::endl;
} however, I get a compiler error I cannot fully understand. What is the correct way to get this working? |
Hello,
so I have a custom map/dictionary data structure, from the cookbook, it seems like it is easy enough to just simply make it a type alias of
std::unordered_map
like so:however this fails to compile, as it seems to be trying to use
daw::construct_a_t
to createmy::sorted_map
from the unordered map, instead of using themap_builder
struct I defined. I have to add the following template specialization to get it to work:Interestingly, I cannot just simply specialize
construct_a_t
. If I remove theconstructor_t
typedef andmap_builder
, compilation also fails. I need to include both for it to work. This seems like an oversight?The text was updated successfully, but these errors were encountered: