Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates std:map作为模板参数的模板推导失败_Templates_C++11 - Fatal编程技术网

Templates std:map作为模板参数的模板推导失败

Templates std:map作为模板参数的模板推导失败,templates,c++11,Templates,C++11,我正在C++11中实现一个简单的LRU缓存。我几乎已经涵盖了它,但只有一个小问题。假设我有以下模板类定义: #ifndef _LRU_STL_H_ #define _LRU_STL_H_ #include <functional> #include <cassert> #include <list> template <typename KeyType, typename ValueType, template<typename...>

我正在C++11中实现一个简单的LRU缓存。我几乎已经涵盖了它,但只有一个小问题。假设我有以下模板类定义:

#ifndef _LRU_STL_H_
#define _LRU_STL_H_

#include <functional>
#include <cassert>
#include <list>

template <typename KeyType, typename ValueType, template<typename...> class Map>
class LRU {

public:
    typedef Map<KeyType, std::pair<ValueType, typename std::list<KeyType>::iterator>> KeyToValueType;

    LRU(const std::function<ValueType(const KeyType&)> &Function, size_t Capacity)
    : _Function(Function), _Capacity(Capacity) {
        assert(_Capacity != 0);
    }

    ...

private:
    ...

    std::function<ValueType(const KeyType&)> _Function;
    const size_t _Capacity;
    KeyToValueType _KeyToValue;
};

#endif
\ifndef\u LRU\u STL\H_
#定义_
#包括
#包括
#包括
模板
类LRU{
公众:
typedef映射KeyToValueType;
LRU(常数标准::功能和功能、大小和容量)
:_功能(功能),_容量(容量){
断言(_容量!=0);
}
...
私人:
...
std::function\u函数;
常数大小和容量;
KeyToValueType _KeyToValue;
};
#恩迪夫
在KeyToValue类型下,我在MSVC2013中遇到以下编译错误:错误1错误C2976:“std::map”:模板参数太少c:\x\visual studio 2013\projects\caching\lru_stl\lru_stl.h 17 1 lru_stl

第17行是:

typedef Map<KeyType, std::pair<ValueType, typename std::list<KeyType>::iterator>> KeyToValueType;
typedef映射KeyToValueType;
似乎模板推导失败了。这可能是一个非常简单的问题,但我就是找不到。为了完整起见,这里有一个例子:

std::function<std::string(std::string)> functionToCache = [](std::string & str) {
    std::string reverse;
    reverse.reserve(str.size());

    std::copy(str.begin(), str.end(), reverse);
    return reverse;
};

LRU<std::string, std::string, std::map> LRU(functionToCache, 5);
std::string Hello_World = LRU("Hello World");
assert(Hello_World == "dlroW olleH");
std::functionToCache=[](std::string&str){
std::字符串反转;
反向保留(str.size());
std::copy(str.begin()、str.end()、reverse);
反向返回;
};
LRU LRU(functionToCache,5);
std::string Hello_World=LRU(“Hello World”);
断言(Hello_World==“dlroW olleH”);
已提供错误信息。完成上述修复。仍然会出现相同的错误:std::map模板参数太少

为了完整起见,如果我删除所有内容并创建一个测试类:

template <typename A, typename B, template <typename ...> class Map>
class TEST {
    typename Map<A, std::pair<B, typename std::list<A>::iterator>> CMAP;
public:
    TEST(void) { }
};
模板
课堂测试{
类型名称映射;
公众:
测试(无效){}
};
尝试实例化该类会产生完全相同的错误消息

@更新: VC++编译器似乎无法在此特定场景中处理默认模板参数。为了解决这个问题,我必须将所有四个模板参数添加到typedef中,因此定义如下:

template <typename K, typename V, template <typename...> class Map>
class Test {
    typedef Map<K, std::pair<V, typename std::list<K>::iterator>, std::less<K>, std::allocator<std::pair<const K, typename std::list<K>::iterator>>> MapType;
};
模板
课堂测试{
typedef映射类型;
};

这就是这个问题的全部。感谢所有试图帮忙的人,感谢那位专业的绅士说:“我对这个问题一点也不知道,让我们投票否决吧!!!”。你真是太棒了!祝你成为伴郎……

你错过了两分

首先,应该是这样的:

模板类名

那么你的

template<typename...> Map
它在g++4.9.1和clang++3.5中都能工作



这似乎是由于VC++的愚蠢。如果您将完整的模板参数赋予
std::map
,包括比较器和分配器,这可能会起作用,因为在这种情况下,VC++似乎无法处理默认模板参数。

也显示使用站点。在询问编译问题时,请始终发布一条消息。这并不意味着整个代码中有一部分会出错。它应该是最小的,完整的,可验证的例子。谢谢你的提示。Map之前的类是我的打字错误,类型名不在那里。正如你写的那样修改了,仍然是同一个错误。@Joey那么,错误信息是什么?你使用的编译器版本是什么?我猜这是因为VC++违反了标准。在这种情况下,错误信息如下:错误C2976:“std::map”:模板参数太少。我的编译器的实际版本是:Microsoft(R)C/C++优化编译器版本18.00.30723x86@Joey这是整个错误信息吗?vcpp应该生成更多的messages>o<无论如何,我猜这是因为
std::map
的额外模板参数,即比较器和分配器。尝试手动提供它们。是的,这就是整个错误消息,直接从VisualStudio按Ctrl+c->Ctrl+v。没有更多,没有更少。。。我不会将任何分配器直接传递给映射。它有一个键和一个std::pair作为其值。即使使用:typename映射KeytoValueType;它失败时会显示相同的错误消息。。。
template<typename...> class Map
#include <list>
#include <map>

template <typename Key, typename Value,
    template <typename...> class Map>
class Test
{
public:
    typedef Map<
        Key,
        std::pair<Value, typename std::list<Key>::iterator>
        > KeyToValueType;
};

int main()
{
    Test<int, char, std::map>::KeyToValueType asdf;
}