Why does compiler say it can't see a template it has just generated?

StephenD

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
Dietmar Kühl

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.

edited at
0

Comments

0 comments
Login to comment

Related

Why can't the compiler see this `From` impl?

Why can't the compiler/JVM just make autoboxing "just work"?

Why can't the compiler deduce to this function template?

Why does my C++ compiler say that a virtual member has no definition?

Can't see why it does not work

Why can't I see the code generated by JIT?

Why does less +F say "can't open '+F'"?

Why does Docker say it can't execute 'bash"?

Compiler can't see argument

I just see project template blazorserver, Why I don't see project template blazor, blazorhosted, blazorlib, blazorserverside?

Android Studio 2.2's incremental compiler can't see generated protobufs

Can't see calls to function or constant value in optimized compiler-generated assembly

Compiler doesn't see template specialization?

Why the rust compiler say that fromIterator isn't implement although I can use it

Why can't the compiler deduce template parameter from return type?

Why a compiler ( say javac ) has to know the size of the object?

Why does the compiler not see the default code in a protocol?

Why can't the compiler see IEnumerable<T> when IReadonlyDictionary<U, T> is also present

Why does configure say no C compiler found when GCC is installed?

Why does the compiler say this macro function needs a closing parenthesis?

Why does my compiler say that my functions are defined multiple times?

Why does the compiler complain that 'not all code paths return a value' when I can clearly see that they do?

Vue-Nuxt: Why can't I see the generated HTMLs correctly?

Why does this template variable lead to a compiler warning?

Why does the compiler have scoping issues with this template?

Why does the compiler issue a template recursion error?

Template "copy constructor" does not prevent compiler-generated move constructor

Why does Chrome on iOS 8.4 say indexedDB is null? Safari has it

why does we need to build a boost library ,isn't it sufficient to just include the head files ,as boost are template

TOP Ranking

HotTag

Archive