为什么编译器说它看不到刚刚生成的模板?
Why does compiler say it can't see a template it has just generated?
如果您查看以下(编辑过的)编译器输出(Visual c++ 2013),您将看到在第5行它告诉我它正在编译(我在预编译的头文件中使用显式实例化):
TimeOnly IT_TimeOnly::operator ++<TimeOnly>(int).
这是IT_TimeOnly
类的模板化后缀操作符。然而,在第7行,编译器警告不能找到IT_TimeOnly
类型的后缀操作符。有人能告诉我为什么吗?我的代码如下所示。
1>------ Build started: Project: TemplatedPostFix, Configuration: Debug Win32 ------
2> stdafx.cpp
3> Precompiled Header
4>c:...it_timeonly.h(14): warning C4305: 'initializing' : truncation from 'int' to 'bool'
5> c:... to_timeonly.h(22) : see reference to function template instantiation 'TimeOnly IT_TimeOnly::operator ++<TimeOnly>(int)' being compiled
6> Test_TemplatedPostFix.cpp
7>c:...test_templatedpostfix.cpp(31): warning C4620: no postfix form of 'operator ++' found for type 'IT_TimeOnly', using prefix form
My Interface类,后缀模板化:
typedef signed char period_t;
class IT_TimeOnly
{
public:
template<class T>
T operator++(int) {
bool b = 2; // here to generate warning for debugging
std::cout << "Template Post++n";
return static_cast<T*>(this)->operator++(1);
}
virtual IT_TimeOnly & operator++() = 0;
virtual period_t getMins() const = 0;
virtual void setMins(period_t) = 0;
};
我的具体派生类:
class TimeOnly : public IT_TimeOnly
{
public:
TimeOnly(){};
TimeOnly(const IT_TimeOnly &);
TimeOnly(const TimeOnly &);
TimeOnly operator++(int);
TimeOnly & operator++() override {
cout << "Derived Pre++n";
++mins;
return *this;
}
period_t getMins() const override;
void setMins(period_t mins) override;
private:
period_t hrs = 0;
period_t mins = 0;
};
我已经在预编译的头文件中显式地实例化了TimeOnly的模板。生成第3、4和5行。
template TimeOnly IT_TimeOnly::operator++<TimeOnly>(int);
我的测试代码:
IT_TimeOnly & myBaseTime = myTime; // Base-class reference
myBaseTime++;
cout << (int)myBaseTime.getMins() << 'n';
// Prints:
// Derived Pre++
// 1
编译器无法从调用中推断出模板参数T
。结果,显式实例化失败。显式实例化的存在是无关紧要的,因为首先确定重载,然后查找或创建实例。但是,函数查找已经失败。
似乎你正试图在基类中定义递增操作符以返回派生类的对象。除非使用派生类型(CRTP)对基类进行参数化,否则这对成员函数不起作用。假设您适当地约束了模板,那么应该可以将操作符实现为非成员,委托给合适的成员函数来执行适当的递增操作。
感谢@ dietmark
所有模板形参不是实参类型的模板化函数的调用必须用模板形参限定,即使你想使用的版本已经被显式实例化。原则上,可以有不同类型的多个实例化,编译器必须知道选择哪一个。
相关文章:
- 为什么我的 FreeRTOS 任务看不到类成员?
- 为什么我看不到字符串?
- 为什么 connect() 函数看不到插槽?
- 为什么即使链接器找到目标文件,我的程序也看不到函数定义?
- 为什么"gdb"看不到全局变量?
- 为什么关闭初始程序后在ncat上看不到UDP?
- 为什么命名空间中的函数看不到全局定义的运算符<<?
- 单例:为什么不需要删除并且看不到析构函数调试消息
- 为什么我看不到被捕获的图像
- 为什么编译器在某些情况下看不到模板类中的错误?
- 为什么内联函数会导致编译器看不到OpenGL函数
- C++链接器错误 - 看不到为什么它没有链接?(包括完整的代码示例)
- 为什么在从 c++ 中的函数返回对象的情况下,我看不到正在调用的复制构造函数?
- 为什么Qt看不到我的插槽?
- 为什么内联函数看不到作用域内部?
- 为什么我看不到任何输出迭代这个向量?
- 为什么我们看不到 #include 粘贴到当前文件中的文本?
- 为什么链接器看不到我的(明确定义的)外部?
- 澄清glFrustum,以及为什么我看不到图像
- 为什么我的C++代码看不到这个 C# 类成员?