value_type盡管分配器是默認的,但由于分配器的不同,以下類將在 std::map 中觸發靜態斷言錯誤:
template < bool store>
class MyClass {
public:
using hashmap_type = std::unordered_map<
int,
decltype([](){})
>;
private:
std::map< int, hashmap_type > m_mapofmaps;
};
通過Myclass<false> v{};觸發器使用它
/opt/compiler-explorer/gcc-11.1.0/include/c /11.1.0/bits/hashtable.h:191:21: error: static assertion failed: unordered container must have the same value_type as its allocator
191 | static_assert(is_same<typename _Alloc::value_type, _Value>{},
可以在這里看到(GCC 11.1):
但是如果非型別模板store被洗掉,編譯器突然就沒有問題了。[](){}將 lambda與另一種型別交換也是如此,請參見此處和此處。
布爾非型別模板、lambda 和分配器之間的這種奇怪的相互作用是什么?
uj5u.com熱心網友回復:
似乎是 gcc 如何將默認引數替換為涉及未評估 lambda 型別的模板引數的錯誤。
一個類似的例子:
#include <type_traits>
template<typename T, typename U = T>
struct assert_is_same {
static_assert(std::is_same_v<T, U>);
};
template<bool B>
struct X {
assert_is_same<decltype([](){})> x;
};
int main() {
X<false> a;
}
沒有template<bool B>,decltype([](){})不是依賴運算式,因此會更急切地評估(最終會得到類似assert_is_same<_ZN1XILb0EEUlvE0_E, _ZN1XILb0EEUlvE0_E>)
在模板內部,[](){}的型別現在依賴于B,因此不能立即用型別替換。似乎 gcc 將其擴展為assert_is_same<decltype([](){}), decltype([](){})>,這兩個 lambdas 現在不同了。(地圖示例中的默認引數是std::allocator<std::pair<const Key, T>>, 或std::allocator<std::pair<const int, decltype([](){})>>)
一種解決方法是給 lambda 一個名為它的東西,它可以隱藏在后面:
private:
static constexpr auto lambda = [](){};
public:
using hashmap_type = std::unordered_map<
int,
decltype(lambda)
>;
// allocator is now `std::pair<const int, decltype(lambda)>`, and
// the two `decltype(lambda)`'s have the same type
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/438900.html
上一篇:為什么我不能獲取std::addressof函式的地址
下一篇:如何在類模板中專門化模板化方法?
