加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – std :: map的变量模板通用lambdas

发布时间:2020-12-16 05:06:38 所属栏目:百科 来源:网络整理
导读:一个 answer to C++14 Variable Templates: what is the purpose? Any usage example?提出了一个变量模板通用lambda的用法示例,它看起来像这样: void some_func() { templatetypename T std::mapint,T storage; auto store = []typename T(int key,const T
一个 answer to C++14 Variable Templates: what is the purpose? Any usage example?提出了一个变量模板通用lambda的用法示例,它看起来像这样:
void some_func() {
    template<typename T>
    std::map<int,T> storage;

    auto store = []<typename T>(int key,const T& value) { storage<T>.insert(key,value) };

    store(0,2);
    store(1,"Hello"s);
    store(2,0.7);

    // All three values are stored in a different map,according to their type. 
}

不幸的是它没有编译所以我试图“修复”它,这是我到目前为止的尝试.

#include <map>

template<typename T>
std::map<int,T> storage;

void some_func() {

    auto store = [](int key,const auto& value) { storage<decltype(value)>.insert(key,value); };

    store(0,std::string("Hello"));
    store(2,0.7);
}

错误消息是:

main.cpp:7:76: error: no matching member function for call to 'insert'

    auto store = [](int key,value); };
                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
main.cpp:10:10: note: in instantiation of function template specialization 'some_func()::<anonymous class>::operator()<std::basic_string<char> >' requested here

    store(1,std::string("Hello"));

当您像所有模板一样实例化变量模板时,每个变量将是不同的类型.理论是auto不会推断出每种类型,但最初只有一种类型(双重).因此代码无效.即使这可行,每个存储实例也会引用不同的变量.

如何重写此代码以实现原始意图?

编辑我在编辑中犯了一个小错误(请参阅修订历史记录以避免文本墙.)decltype(pair)应该是decltype(pair.second),因为存储只有一个模板参数.

#include <map>

template <typename T>
std::map<int,T> storage;

void some_func() {
    auto store = [&](auto pair) { storage<decltype(pair.second)>.insert(pair); };

    store(std::pair<int,int>(0,1));
    store(std::pair<int,std::string>(1,"Hello!"));
    store(std::pair<int,int>(2,3));
}

int main()
{
}

现在有链接器错误.

/tmp/main-5f1f7c.o: In function `some_func()':
main.cpp:(.text+0x1a): undefined reference to `storage<int>'
main.cpp:(.text+0x43): undefined reference to `storage<std::string>'
main.cpp:(.text+0x74): undefined reference to `storage<int>'

为了修复链接器错误,我认为你需要显式实例化参数? (我甚至不确定这是否是正确的术语.)

template <typename T>
std::map<int,T> storage;

template <>
std::map<int,int> storage<int>;

template <>
std::map<int,std::string> storage<std::string>;

Live Example

解决方法

template<typename T>
std::map<int,T> storage;

这是一个声明,很像例如模板< typename T> class foo;无论如何我们还需要一个,我们也可以从定义中获益:

template<typename T>
std::map<int,T> storage {};

然而,这并没有消除链接器错误,这表明隐式实例化存在一个突出的错误.为了说服自己,我们可以通过各种方式触发实例化:

>明确地,看起来像

// namespace scope,same as storage
template /* sic */ std::map<int,int>         storage<int>;
template           std::map<int,std::string> storage<std::string>;

>隐式地,通过在main中添加以下内容

storage<int>.size();
storage<std::string>.size();

在任何一种情况下驯服链接器.

您尝试的是显式专业化,尽管使用了不同的机制,但它确实解决了这个问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读