模板上的密码错误
Cryptic error on templates
我看到的一段代码的错误消息让我很困惑。我试着提取最相关的代码片段,让它看起来很容易。
我看到的错误:
错误:对"
Map(Print&, std::shared_ptr< LinkedList< int> >&)
"的调用没有匹配的函数
注意:模板参数推导/替换失败:无法将"p
"(类型为"int
"
编译器为什么要将Print
强制转换为int
?
template<typename T>
class LinkedList
{
public:
using NodeType = std::shared_ptr<LinkedList>;
... Other things
}
template<class Func, typename T>
typename LinkedList<T>::NodeType Map(Func func, typename LinkedList<T>::NodeType seq)
{
// Some stuff
}
class Print
{
public:
int operator()(int i)
{
cout << i << endl;
return i;
}
};
void main()
{
Print p;
auto one = std::make_shared< LinkedList <int>> ();
auto result = Map<int>(p, one); << ---- Error
}
gcc 4.8.4
感谢阅读。
如果我这样做,我会将Map定义为LinkedList的内联好友。这消除了依赖类型推导的问题,因此您可以在没有任何显式模板参数的情况下调用Map
。
请记住,编译器查找这样定义的函数的唯一方法是使用参数相关查找,因此只有当LinkedList
对象作为函数的参数之一传递时,它才有效。同样在线的朋友似乎会让人抓狂。
但是,清理和简化代码还有很长的路要走。
#include <iostream>
#include <memory>
template<typename T>
class LinkedList
{
public:
using NodeType = std::shared_ptr<LinkedList>;
template <typename Func>
friend NodeType Map(Func func, NodeType seq) {
return seq;
}
};
class Print
{
public:
int operator()(int i)
{
std::cout << i << std::endl;
return i;
}
};
int main()
{
Print p;
auto one = std::make_shared< LinkedList<int> >();
auto result = Map(p, one);
}
在更好地了解OP的目标后,我添加了一个新的答案。我的第一个答案解决了编译一些示例代码时遇到的与依赖模板类型参数相关的困难,所以我认为这仍然是一个有效的答案。
这个答案演示了创建一个自定义容器类,以及如何编写一个在容器上迭代的通用Map
函数,为每个元素调用一个自定义函数对象,并将每个结果添加到另一个容器中,该容器最终由函数返回。
这个例子中的容器是一个链表,用一组最小的特性定义,只够这个例子编译和运行。
链表类提供begin()
和end()
函数,它们返回用于遍历列表的迭代器对象。这里只定义了非常量版本,当LinkedList对象为常量时,还应该添加返回常量迭代器的版本。
这里的Map
函数采用一个函子和一个容器对象作为参数。所有参数类型都是推导出来的,因此不需要显式提供模板参数。容器是按值传递的,以避免LinkedList中的常量正确性问题,也因为LinkedList
的(默认)复制构造函数不需要做很多工作——它只需要复制两个shared_ptr
对象,而不需要对所有包含的数据执行深度复制。
这个Map
非常简单,额外的改进版本可能需要两个迭代器(一个开始和结束),对容器对象进行const引用(以避免无用的复制),或者使用类型特征来处理需要以特殊方式访问的容器。
在这里,Map
应该与其他容器一起工作,比如std::vector,因为它使用标准迭代器API。
LinkedList的原始版本只是作为指向单个列表节点的指针进行维护。在下面的代码中,LinkedList
实际上是一个容器对象,它保留了指向第一个和最后一个Node
对象的(智能)指针。我们需要同时访问指向head
和tail
节点的指针,因此只保留指向一个节点的指针是不够的。
#include <iostream>
#include <memory>
#include <string>
template<typename T>
class LinkedList {
public:
struct Node;
using NodeType = std::shared_ptr<Node>;
struct Node {
NodeType next;
T value;
};
class forward_iterator {
NodeType cur_node;
public:
forward_iterator() {}
forward_iterator(NodeType cur_node) : cur_node(cur_node) {}
T& operator * () { return cur_node->value; }
forward_iterator& operator ++ () { cur_node = cur_node->next; return *this; }
bool operator == (const forward_iterator& it) const { return cur_node == it.cur_node; }
bool operator != (const forward_iterator& it) const { return !operator == (it); }
};
void push_back(const T& t) {
NodeType node = std::make_shared<Node>();
if(tail) {
tail->next = node;
tail = node;
} else {
head = tail = node;
}
node->value = t;
}
forward_iterator begin() { return forward_iterator(head); }
forward_iterator end() { return forward_iterator(); }
protected:
NodeType head, tail;
};
inline std::string upper_case(const std::string& s) {
std::string r;
for(auto c : s) {
if(c >= 'a' && c <= 'z') c = c - 'a' + 'A';
r.push_back(c);
}
return r;
}
template <typename Func, typename S>
inline S Map(Func func, S seq) {
S result;
for(const auto& elem : seq) {
result.push_back(func(elem));
}
return result;
}
int main() {
// add strings to a LinkedList of strings named "original"
static const char* my_data[] = { "Hello", "1234", "John Cena", "xd" };
LinkedList<std::string> original;
for(auto cstr : my_data) { original.push_back(cstr); }
// dump "original" to cout
std::cout << "-- original --n";
for(const auto& s : original) { std::cout << s << 'n'; }
std::cout << 'n';
// Run the generic Map function with "original" as input
// A lambda will be called for each element and
// its returned value added to the result, named "mapped".
// A functor object may be used in place of the lambda
auto mapped = Map(
[](const std::string& s) { return upper_case(s); },
original);
// dump "mapped" to cout
std::cout << "-- mapped --n";
for(const auto& s : mapped) { std::cout << s << 'n'; }
std::cout << 'n';
}
- 警告处理为错误这里有什么问题
- 在 c++e 中使用 do-while 循环进行密码检查功能时出现错误"code will never execute"
- 在我的C++凯撒密码程序中出现错误
- C++ 密码解密错误NTE_BAD_DATA
- 随机密码生成器的C++循环错误"以非零状态退出"
- 特征错误:请使用密码保护您的最小值
- c++Boost asio错误:没有共享密码
- 模板上的密码错误
- 快速修复管理员以添加用户名,密码错误
- 维杰尼雷密码错误在C++
- LogonUser 返回 true 表示密码错误
- 密码模板模板参数错误
- 错误在哪里?显示字符串C++Vignere密码
- 用c++验证密码并给出特定错误
- 凯撒密码与扭曲(神秘错误)
- c++凯撒密码程序执行错误字符
- 出现错误后需要帮助重置密码
- 密码HRESULT错误
- 密码套件错误或与OpenSSL服务器没有连接
- c++中用户名/密码检查器错误