Home >Backend Development >C++ >How Can C Traits Solve Compilation Issues with Static Polymorphism and Typedefs in the Curiously Recurring Template Pattern?

How Can C Traits Solve Compilation Issues with Static Polymorphism and Typedefs in the Curiously Recurring Template Pattern?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-11 01:51:09229browse

How Can C   Traits Solve Compilation Issues with Static Polymorphism and Typedefs in the Curiously Recurring Template Pattern?

Static Polymorphism and Typedefs in C

Curiously Recurring Template Pattern (CRTP) is a technique in C to achieve static polymorphism. However, when attempting to generalize this pattern to modify return types based on derived types, the code may not compile, as encountered by a user using MSVC 2010.

Issue:

The following code, intended to allow different return types in the derived class, fails to compile:

template <typename derived_t>
class base {
public:
    typedef typename derived_t::value_type value_type;
    value_type foo() {
        return static_cast<derived_t*>(this)->foo();
    }
};

template <typename T>
class derived : public base<derived<T>> {
public:
    typedef T value_type;
    value_type foo() {
        return T();
    }
};

The error encountered is "is not a member of 'derived'.'" This occurs because the derived type is incomplete when used as a template argument for its base class.

Solution using Traits:

A common workaround is to employ a traits class template. In this approach, a base_traits class template is defined to encapsulate both types and functions from the derived class. The original base class is modified to use these traits.

template <typename derived_t>
struct base_traits;

template <typename derived_t>
struct base {
    typedef typename base_traits<derived_t>::value_type value_type;
    value_type base_foo() {
        return base_traits<derived_t>::call_foo(static_cast<derived_t*>(this));
    }
};

template <typename T>
struct derived : base<derived<T>> {
    typedef typename base_traits<derived>::value_type value_type;
    value_type derived_foo() {
        return value_type();
    }
};

template <typename T>
struct base_traits<derived<T>> {
    typedef T value_type;
    static value_type call_foo(derived<T>* x) {
        return x->derived_foo();
    }
};

By specializing the base_traits class for each type used in the derived template argument, the desired types and functions can be accessed through the traits, enabling both static polymorphism and dynamic return types.

The above is the detailed content of How Can C Traits Solve Compilation Issues with Static Polymorphism and Typedefs in the Curiously Recurring Template Pattern?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn