以下代码使用gcc 5.2,gcc 4.9和clang 3.7在C ++ 11标准下编译:
template <typename T, typename U, template<typename...> class M>
U * find_item(M<T, U> & m, const T & t) {
auto it = m.find(t);
if (it != m.end()) { return &it->second; }
return nullptr;
}
template <typename T, typename U, template<typename...> class M>
const U * find_item(const M<T, U> & m, const T & t) {
auto it = m.find(t);
if (it != m.end()) { return &it->second; }
return nullptr;
}
#include <map>
#include <unordered_map>
#include <string>
#include <iostream>
int main() {
std::map<std::string, int> foo;
foo["asdf"] = 5;
if (find_item(foo, std::string{"bar"})) { std::cerr << "hmm\n"; }
}
但是,当我使用最新版本的emscripten编译它时,我收到来自too few arguments for class template 'map'
的编译器错误:
main.cpp:24:7: error: no matching function for call to 'find_item'
if (find_item(foo, std::string{"bar"})) { std::cerr << "hmm\n"; }
^~~~~~~~~
main.cpp:2:5: note: candidate template ignored: substitution failure [with T =
std::__1::basic_string<char>, U = int, M = map]: too few template
arguments for class template 'map'
U * find_item(M<T, U> & m, const T & t) {
^ ~
main.cpp:9:11: note: candidate template ignored: substitution failure [with T =
std::__1::basic_string<char>, U = int, M = map]: too few template
arguments for class template 'map'
const U * find_item(const M<T, U> & m, const T & t) {
^ ~
1 error generated.
ERROR:root:compiler frontend failed to generate LLVM bitcode, halting
这有点奇怪,因为我的emscripten声称是基于clang-3.7。无论如何,在实例化find_item
模板时似乎很难推断出默认参数。
如果代码以下列方式更改,那么所有编译器似乎都对此感到满意:
template <typename T, typename U, template<typename...> class M, typename... dummy>
U * find_item(M<T, U, dummy...> & m, const T & t) {
auto it = m.find(t);
if (it != m.end()) { return &it->second; }
return nullptr;
}
template <typename T, typename U, template<typename...> class M, typename... dummy>
const U * find_item(const M<T, U, dummy...> & m, const T & t) {
auto it = m.find(t);
if (it != m.end()) { return &it->second; }
return nullptr;
}
#include <map>
#include <unordered_map>
#include <string>
#include <iostream>
int main() {
std::map<std::string, int> foo;
foo["asdf"] = 5;
if (find_item(foo, std::string{"bar"})) { std::cerr << "hmm\n"; }
}
问题是,如果&#34;虚拟&#34;根据C ++ 11标准实际上是必要的部分,还是emscripten有缺陷而没有在这里找出默认的模板参数?
我对[temp.deduct.type] 14.8.2.6.8
部分的解读是,它应该能够将std::map
绑定到M<T, U>
形式的模板模板参数,因为措辞&#34;至少有一个&#34; 34;在这句话中:
类似地,&lt; T&gt;代表模板参数 列出至少一个参数包含T
的列表
但是,我对此并不确定。
答案 0 :(得分:1)
我遇到了这个问题,发现我不需要虚拟模板参数,指定模板模板为variadic就足够了(这是在clang 3.6上):
template <typename T, typename U, template<typename...> class M>
U * find_item(M<T, U> & m, const T & t) {
auto it = m.find(t);
if (it != m.end()) { return &it->second; }
return nullptr;
}
template <typename T, typename U, template<typename...> class M>
const U * find_item(const M<T, U> & m, const T & t) {
auto it = m.find(t);
if (it != m.end()) { return &it->second; }
return nullptr;
}