Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
308 views
in Technique[技术] by (71.8m points)

c++ - CRTP with full template specialization

Why is the following code is not correct?

template <typename T>
class B {
public:
    auto foo() -> decltype(static_cast<T*>(this)->foo()) {
        return static_cast<T*>(this)->foo();
    }
};
    
template <typename X>
class A: public B<A<X>> {
public:
    X foo();
};
    
template <>
class A<int>: public B<A<int>> {
public:
    int foo();
};

Compiler gives the following error (highlighting decltype(static_cast<T*>(this)->foo()) part):

static_cast from 'B<A<int>> *' to 'A<int> *', which are not related by inheritance, is not allowed
in instantiation of template class B<A<int>> requested here
'A' is incomplete
'B' is incomplete

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Issue with CRTP, is that derived is incomplete from CRTP.

So

-> decltype(static_cast<T*>(this)->foo())

is problematic for 2 reasons, as T is incomplete:

  • it is not yet derived class of B<T>, std::declval<T>().foo() might solve that issue.
  • T::foo is not yet declared.

Possible solution is to get rid of explicit return type, and use just auto which is delayed to method instantiation.

template <typename T>
class B {
public:
    auto foo()
    {
        return static_cast<T*>(this)->foo();
    }
};

Demo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...