Использование предварительного объявления в файле шаблона с типом охранников - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь объединить предварительные объявления в библиотеке шаблонов с защитой типов для перехвата случаев использования неправильного типа шаблона с неправильным типом класса. Вот простейший фрагмент кода, к которому я могу обратиться, чтобы проиллюстрировать проблему ...

main.cpp

#include <iostream>
#include "templates.h"

int main()
{
    B<int_array> hello;
    return 0;
}

templates.h

#include <type_traits>

#define USE_GUARD
#define FORWARD_DECLARE

template<typename T>
using is_pod = typename std::enable_if<std::is_pod<T>::value>::type;

typedef struct {
    int *p; 
    int n;   
} int_array;

template <typename E, typename T >
class A
{

};

#ifdef USE_GUARD
template <typename T, typename = is_pod<typename std::remove_pointer<decltype(T::p)>::type> >
#else
template <typename T>
#endif
class B : public T, public A< B<T>, T >
{                                     // This is the 'curiously recurring template
                                      // pattern' (CRTP)
public:
    //! Default constructor
    B() noexcept
    {
        T::p = nullptr;
        T::n = 0;
    }

#ifdef FORWARD_DECLARE
    void reorder(const int_array & newOrder);
#endif
};

template <typename T> class C : public B<T>
{
public:
    C() noexcept : B<T>()
    {
        T::p = nullptr;
        T::n = 0;
    }
};

#ifdef FORWARD_DECLARE
#ifdef USE_GUARD
template <typename T, typename = is_pod<typename std::remove_pointer<decltype(T::p)>::type> >
#else
template <typename T>
#endif
void B<T>::reorder(const int_array & newOrder)
{
    C<T> myC;
}
#endif

Я получаю сообщения об ошибках следующим образом:

Visual Studio 2015:

Не определены ни USE_GUARD, ни FORWARD_DECLARE - работает нормально

Определяется только FORWARD_DECLARE - отлично работает

Определяется только USE_GUARD - отлично работает

Оба определены - C3860: template argument lost following class template name must list parameters in the order used in template parameter list

г ++:

Не определены ни USE_GUARD, ни FORWARD_DECLARE - работает нормально

Определяется только FORWARD_DECLARE - отлично работает

Определяется только USE_GUARD - отлично работает

Оба определены - Invalid use of incomplete type 'class B<T> в точке, где определена функция 'reorder'

Так что, очевидно, я что-то не так делаю, когда комбинирую защиту типов с предварительным объявлением, но ни один компилятор не дает мне очень понятного сообщения об ошибке. Я делаю элементарную ошибку в своем синтаксисе или просто пытаюсь сделать что-то глупое?

1 Ответ

0 голосов
/ 05 сентября 2018

Аргумент по умолчанию не должен повторяться в определении элемента, и должны быть указаны все аргументы:

#ifdef FORWARD_DECLARE
# ifdef USE_GUARD
template <typename T, typename U>
void B<T, U>::reorder(const int_array & newOrder)
# else
template <typename T>
void B<T>::reorder(const int_array & newOrder)
# endif
{
    C<T> myC;
}
#endif

Демо

...