If you look at the following (edited) compiler output (Visual C++ 2013) you will see that on line 5 it tells me it is compiling (I use an explicit instantiation in a precompiled header):
TimeOnly IT_TimeOnly::operator ++<TimeOnly>(int).
This is the templated postfix operator for IT_TimeOnly
class. However, on line 7 the compiler warns that a postfix operator for type IT_TimeOnly
cannot be found. Can anyone help me understand why? My code is shown below.
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;
};
My concrete derived class:
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;
};
I have explicitly instantiated the template for TimeOnly in my pre-compiled header. That produces lines 3, 4 and 5.
template TimeOnly IT_TimeOnly::operator++<TimeOnly>(int);
And my test code:
IT_TimeOnly & myBaseTime = myTime; // Base-class reference
myBaseTime++;
cout << (int)myBaseTime.getMins() << '\n';
// Prints:
// Derived Pre++
// 1
The compiler can't deduce the template argument T
from the call. As a result the explicit instantiation fails. The existance of an explicit instantiation is irrelevant as first the overload is determined, then an instantion is looked for or created. However, the function look-up already fails.
It seems you are trying to define you increment operator in the base class to return an object of the derived class. That's not going to work for a member function unless you parameterize the base with the derived type (CRTP). Assuming you constrain the template appropriately it should be possible to implement the operator as a non-member delegating to a suitable member function to do the appropriate increment.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments