Я пытаюсь объединить предварительные объявления в библиотеке шаблонов с защитой типов для перехвата случаев использования неправильного типа шаблона с неправильным типом класса. Вот простейший фрагмент кода, к которому я могу обратиться, чтобы проиллюстрировать проблему ...
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'
Так что, очевидно, я что-то не так делаю, когда комбинирую защиту типов с предварительным объявлением, но ни один компилятор не дает мне очень понятного сообщения об ошибке. Я делаю элементарную ошибку в своем синтаксисе или просто пытаюсь сделать что-то глупое?