Created
April 14, 2021 07:30
-
-
Save skyline75489/e286756e0b65d69515866b710c2ce17f to your computer and use it in GitHub Desktop.
MSVC bug with nested templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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