【问题标题】:Accessing variable template using decltype使用 decltype 访问变量模板
【发布时间】:2022-12-05 02:22:01
【问题描述】:

显示问题的代码的最小化示例:

#include <cassert>
#include <iostream>
#include <map>
#include <string>

template <typename T>
const std::map<std::string, T> smap;

template <>
const std::map<std::string, bool> smap<bool>{{"a", false}};

int main() {
    std::map<bool, std::string> rmap{{false, "x"}};

    for (const auto& [key, val] : rmap) {
        std::cerr << typeid(bool).hash_code() << "\n";
        std::cerr << typeid(decltype(key)).hash_code() << "\n";

        std::cerr << smap<bool>.size() << "\n";
        std::cerr << smap<decltype(key)>.size() << "\n";

        assert((std::is_same_v<bool, decltype(key)>));
    }

    return 0;
}

Godbolt

它给出了输出:

10838281452030117757
10838281452030117757
1
0
example.cpp:22: int main(): Assertion `(std::is_same_v<bool, decltype(key)>)' failed.

为什么当引用相同类型 (bool) 时,我无法使用 decltype 访问变量模板?

为了记录在案,我还尝试不使用结构化绑定并在对中的第一个上使用 decltype 并获得相同的结果。

但是,如果我创建一个实际的 bool 变量,就像这样......

bool b;
std::cerr << settings_map<decltype(b)>.size() << "\n";

...它的工作。

【问题讨论】:

    标签: c++ templates decltype


    【解决方案1】:

    value_type是std::pair&lt;const Key, T&gt;,所以decltype(key)是const bool,而不是bool


    你通过const auto&amp;捕获它所以它是const

    【讨论】:

      【解决方案2】:

      密钥是const,因此您需要将其删除才能使断言通过。

      assert((std::is_same_v<bool, std::remove_cv_t<decltype(key)>>));
      

      【讨论】:

        【解决方案3】:

        decltype(key) 是 const bool,而不是 bool。而 typeid 去除了 const 限定符,因此两者具有相同的(运行时)表示。

        如果类型或表达式的类型是 cv 限定的,则 typeid 的结果引用表示 cv 非限定类型的 std::type_info 对象(即 typeid(const T) == typeid(T))。

        因此,虽然 typeid 将这两种类型视为等同的,但模板扩展(和 is_same_v)却不同,您会得到两个不同的映射:一个用于 bool,一个用于 const bool。请注意,断言

        assert((std::is_same_v<const bool, decltype(key)>));
        

        如果将其替换为您的代码中的代码,则会成功。要删除 cv 限定符,请使用 remove_cv_t。

        std::cerr << settings_map<std::remove_cv_t<decltype(key)>>.size() << "
        ";
        

        在你最后的 sn-p

        bool b;
        std::cerr << settings_map<decltype(b)>.size() << "
        ";
        

        b 是不是常量,所以 decltype(b) 实际上是 bool,而不是 const bool。

        【讨论】:

        • 对 - 有道理,我认为 typeid 会包含 const,很高兴知道。
        猜你喜欢
        • 2020-01-26
        • 2014-02-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-29
        • 2022-11-07
        • 2017-12-28
        • 2018-09-21
        • 2011-12-22
        相关资源
        最近更新 更多