这个';缺少模板参数';C++;错误 AHH,C++模板…

这个';缺少模板参数';C++;错误 AHH,C++模板…,c++,templates,C++,Templates,我看到的代码, 对我来说很有意义, 但是GCC… 它不同意 以下代码按预期编译和运行,但如果您取消注释#define,则会出现错误,我不理解。符号迭代器仍然只能引用一个东西:超类中的typedef。所以我想我有两个问题:1。这些错误意味着什么?2.修复它们的最佳方法是什么 #include <map> #include <string> #include <cstdio> using namespace std; // #define WITH_TEMPL

我看到的代码,
对我来说很有意义,
但是GCC…
它不同意

以下代码按预期编译和运行,但如果您取消注释
#define
,则会出现错误,我不理解。符号迭代器仍然只能引用一个东西:超类中的typedef。所以我想我有两个问题:1。这些错误意味着什么?2.修复它们的最佳方法是什么

#include <map>
#include <string>
#include <cstdio>

using namespace std;

// #define WITH_TEMPLATE 1

#ifdef WITH_TEMPLATE
template <class C>
struct MyClass : public map<string, C>
#else
struct MyClass : public map<string, int>
#endif
{
    bool haskey(const string &s)
    {
        iterator it = find(s);
        return (it != end());
    }
};

int main()
{
#ifdef WITH_TEMPLATE
    MyClass<int> m;
#else
    MyClass m;
#endif
    m["test"] = 10;    
    printf("%d %d\n", m.haskey("test"), m.haskey("no"));
}
#包括
#包括
#包括
使用名称空间std;
//#使用_模板1定义
#带_模板的ifdef
模板
结构MyClass:公共映射
#否则
结构MyClass:公共映射
#恩迪夫
{
布尔哈斯基(常量字符串和s)
{
迭代器it=find(s);
返回(it!=end());
}
};
int main()
{
#带_模板的ifdef
MyClass m;
#否则
MyClass m;
#恩迪夫
m[“试验”]=10;
printf(“%d%d\n”,m.haskey(“测试”),m.haskey(“否”);
}
来自GCC的错误:

temp.cc:在成员函数“bool MyClass::haskey(const std::string&)”中:
temp.cc:18:错误:在“it”之前缺少模板参数
临时抄送:18:错误:应为“;”在“它”之前
临时抄送:19:错误:“它”未在此范围内声明
temp.cc:19:错误:没有依赖于模板参数的'end'参数,因此'end'声明必须可用
temp.cc:19:error:(如果您使用'-fppermissive',G++将接受您的代码,但不赞成使用未声明的名称)

这条线应该是,

#ifdef WITH_TEMPLATE
           typename map<string, C>::iterator it = this->find(s);
           return (it != this->end()); 
#else
           map<string, int>::iterator it = find(s);
           return (it != end());
#endif
#带模板的ifdef
typename映射::迭代器it=this->find(s);
return(it!=this->end());
#否则
map::iterator it=find(s);
返回(it!=end());
#恩迪夫

您还需要更改MyClass::haskey方法

bool haskey(const string &s)
{
    typename MyClass<C>::iterator it = this->find(s);
    return (it != this->end());
}
bool haskey(常量字符串&s)
{
typename MyClass::iterator it=this->find(s);
return(it!=this->end());
}
关于这种行为的解释请参见上的“名称查找、模板和访问基类成员”一节(链接自另一个答案的注释,以防万一)


完整的固定示例代码:

您是否尝试过string::iterator?@Nawaz以便派生类看不到基类typedefs?@Ashot:当基类是模板时,编译器在解析时无法知道该类是否实际包含该typedef。因此,必须显式地使用typename来引用类型。@Ashot:如果基类依赖于模板参数(即,要使用的基类可以根据模板参数更改),则不能这样做。请看一些信息。@Jeremiah Willcock感谢您的解释。我认为这必须添加到答案中。我可能很快会将其标记为答案,但如果有人可以编辑并添加1则更好。从非模板部件中删除map::。2.在答案中添加耶利米的链接或类似的解释。这个解释回答了我问题的“为什么”部分。谢谢。我会将此标记为答案,但它不能解释错误的原因。这个解释在另一个答案中的一个链接中。这个链接被破坏或隐藏在付费墙后面。有最新的参考资料吗?
bool haskey(const string &s)
{
    typename MyClass<C>::iterator it = this->find(s);
    return (it != this->end());
}