Skip to content

Instantly share code, notes, and snippets.

@skyline75489
Created April 14, 2021 07:30
Show Gist options
  • Save skyline75489/e286756e0b65d69515866b710c2ce17f to your computer and use it in GitHub Desktop.
Save skyline75489/e286756e0b65d69515866b710c2ce17f to your computer and use it in GitHub Desktop.
MSVC bug with nested templates
#include <string>
#include <algorithm>
#include <iostream>
template<typename Result, typename Functor>
struct functor_storage : Functor
{
functor_storage() = default;
functor_storage(const Functor& functor)
: Functor(functor)
{
}
template<typename... Args>
Result operator()(Args &&... args)
{
return static_cast<Functor&>(*this)(std::forward<Args>(args)...);
}
template<typename... Args>
Result operator()(Args &&... args) const
{
return static_cast<const Functor&>(*this)(std::forward<Args>(args)...);
}
};
template<typename key_type, typename value_type, typename hasher>
struct KeyOrValueHasher : functor_storage<uint64_t, hasher>
{
typedef functor_storage<uint64_t, hasher> hasher_storage;
KeyOrValueHasher() = default;
KeyOrValueHasher(const hasher& hash)
: hasher_storage(hash)
{
}
uint64_t operator()(const key_type& key)
{
return static_cast<hasher_storage&>(*this)(key);
}
uint64_t operator()(const key_type& key) const
{
return static_cast<const hasher_storage&>(*this)(key);
}
uint64_t operator()(const value_type& value)
{
return static_cast<hasher_storage&>(*this)(value.first);
}
uint64_t operator()(const value_type& value) const
{
return static_cast<const hasher_storage&>(*this)(value.first);
}
template<typename F, typename S>
uint64_t operator()(const std::pair<F, S>& value)
{
return static_cast<hasher_storage&>(*this)(value.first);
}
template<typename F, typename S>
uint64_t operator()(const std::pair<F, S>& value) const
{
return static_cast<const hasher_storage&>(*this)(value.first);
}
};
template<typename K, typename V, typename Hasher>
class fake_hash_table: private Hasher
{
public :
fake_hash_table()
{
}
fake_hash_table(fake_hash_table&& other)
: Hasher(std::move(other))
{
}
};
template<typename K, typename V, typename H = std::hash<K>>
class fake_hash_map
: public fake_hash_table
<
std::pair<K, V>,
K,
KeyOrValueHasher<K, std::pair<K, V>, H>>
{};
struct Hasher {
size_t operator()(const std::string& descriptor) const;
};
size_t Hasher::operator()(const std::string& descriptor) const {
return 1;
}
int main() {
try
{
fake_hash_map<std::string, std::string, Hasher> map;
auto map2 = std::move(map);
} catch (std::exception &e)
{
std::cout << e.what() <<std::endl;
}
getchar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment