constexpr
및 std::array
을 사용하여 간단한 컴파일 시간 Bimap을 만들려고합니다.컴파일 시간 Bimap static_assert 실패
첫 번째 예제에서는 문제가없는 것 같습니다. 여기
error: static_assert failed "3 == 3.3"
static_assert(meta_dict.find_key_of_value(3) == 3.3, "3 == 3.3"); // fails
Wandbox에서 사용할 수있는 코드 : 그러나 두 번째 예제와 나는 다음과 같은 정적 오류가 있습니다. 위의 오류를 제외하고 Clang>=5.0.0
및 GCC>=8.0.0
을 사용하여 컴파일해야합니다.
#include <utility>
#include <array>
#include <stdexcept>
#include <string_view>
#include <iostream>
template<class Key, class Value, std::size_t N>
struct MetaBimap {
using Item = std::pair<Key, Value>;
constexpr MetaBimap(const std::array<Item, N>& d)
: dictionnary{d}
{}
constexpr Value find_value_of_key(const Key& key, int range = N) const
{
if (range == 0)
throw std::out_of_range("Cannot find key");
return (dictionnary[range - 1].first == key)
? dictionnary[range - 1].second
: find_value_of_key(key, range - 1);
}
constexpr Key find_key_of_value(const Value& value, int range = N) const
{
if (range == 0)
throw std::out_of_range("Cannot find value");
return (dictionnary[range - 1].second == value)
? dictionnary[range - 1].first
: find_key_of_value(value, range - 1);
}
std::array<Item, N> dictionnary;
};
int main()
{
// first example
{
using namespace std::string_view_literals;
constexpr std::array<std::pair<std::string_view, int>, 3> meta_array {{
{ "one"sv, 1 },
{ "two"sv, 2 },
{ "three"sv, 3 }
}};
constexpr MetaBimap<std::string_view, int, 3> meta_dict = meta_array;
// OK on wandbox with Clang>=5.0.0 and GCC>=8.0.0 (though not working on my computer with Clang=5.0.0)
static_assert(meta_dict.find_value_of_key("one"sv) == 1, "one == 1");
static_assert(meta_dict.find_key_of_value(3) == "three"sv, "3 == three");
}
// second example
{
constexpr std::array<std::pair<float, int>, 3> meta_array {{
{ 1.1, 1 },
{ 2.2, 2 },
{ 3.3, 3 }
}};
constexpr MetaBimap<float, int, 3> meta_dict = meta_array;
static_assert(meta_dict.find_value_of_key(1.1) == 1, "1.1 == 1"); // OK
std::cout << meta_dict.find_key_of_value(3) << std::endl;
// static_assert(meta_dict.find_key_of_value(3) == 3.3, "3 == 3.3"); // fails
}
}
왜 여기에 정전기 오류가 발생하며이를 수정하는 이유는 무엇입니까? 또한 보너스로 bimap의 구성을 단순화하는 방법은 무엇입니까?
이것은 부동 소수점 숫자를 사용하면 키가 가장 위험하다는 것을 보여줍니다. – Walter
확실히 @ 월터! –
@GianPaolo 젠장, 어리 석다. .. 고마워. – coincoin