如果您查看以下(已编辑的)编译器输出(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 class with templated postfix:
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
答案 0 :(得分:1)
编译器无法从调用中推导出模板参数T
。结果,显式实例化失败。显式实例化的存在是无关紧要的,因为首先确定过载,然后查找或创建实例。但是,函数查找已经失败。
您似乎正在尝试在基类中定义增量运算符以返回派生类的对象。除非使用派生类型(CRTP)参数化基数,否则这对成员函数不起作用。假设您适当地约束模板,应该可以将操作符实现为非成员,委托给合适的成员函数来执行适当的增量。
答案 1 :(得分:0)
感谢@DietmarKühl和@vsoftco提供的有用答案。总结一下你的答案:......
对模板参数不是参数类型的模板化函数的所有调用必须使用template参数进行限定,即使您要使用的版本已经显式实例化。原则上可以有多个不同类型的实例化,编译器必须知道选择哪个。