c – std :: map的变量模板通用lambdas
一个
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(); 在任何一种情况下驯服链接器. 您尝试的是显式专业化,尽管使用了不同的机制,但它确实解决了这个问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |