Явный шаблонный экземпляр и SFINAE

Я получаю ошибку компиляции так ясно, что я делаю что-то не так, но я не уверен, как это исправить, и нет ли возможности иметь явное создание экземпляра и SFINAE. Воспроизводимый пример минимален, поэтому он может не иметь полного смысла, но, по сути, существует класс, похожий на вектор, который может быть создан для unique_ptr или Observer_ptr. Часть SFINAE предназначена только для того, чтобы функция добавления была доступна только для unique_ptr.

Я получил там определение CompilationFail. Кажется, что если Bar имеет FooPtrVectorView, то я получаю ошибку компиляции. Если я не определяю это, тогда все хорошо. Если я просто использую FooPtrVectorView, скажем, в функции (а не часть Bar) нет никаких проблем.

Ошибка компилятора для msvc - это ошибка C3190: "Foo *FooSmartPtrVector::add(void)" с предоставленными аргументами шаблона не является явным созданием какой-либо функции-члена "FooSmartPtrVector"

Для пользователей msvc у меня есть zip-файл со всем решением, которое может упростить его https://app.box.com/s/nzbgvxo58u4jmiw50o1hlh28yfyxo1d1

observer_ptr.h

template<typename T>
class observer_ptr
{
};

Foo.h и остальная часть реализации в.cpp

struct Foo{};

FooSmartPtrVector.h

#define CompilationFail 1

class Bar;
// this has to be forward declared in my case
struct Foo; 

template<template<class...> class SmartPtr>
class FooSmartPtrVector 
{
public:
    #if CompilationFail
    const Foo* fooBar(const Bar* const bar) const;
    #endif

    template<template<class...> class Q = SmartPtr,
             typename std::enable_if_t<std::is_same<Q<Foo>, std::unique_ptr<Foo>>::value>* = nullptr>
    Foo* add();

private:
    std::vector<SmartPtr<Foo>> vec;
};

using FooPtrVectorView = FooSmartPtrVector<nonstd::observer_ptr>;
using FooPtrVector = FooSmartPtrVector<std::unique_ptr>;

FooSmartPtrVector.cpp

#include "FooSmartPtrVector.h"

#if CompilationFail
    #include "Bar.h"
#endif 

#if CompilationFail
template<template<class...> class SmartPtr>
const Foo* FooSmartPtrVector<SmartPtr>::fooBar(const Bar* const bar) const
{
    return bar->getFromFooPtrView();
}
#endif 

template<template<class...> class SmartPtr>
template<template<class...> class Q,
         typename std::enable_if_t<std::is_same<Q<Foo>, std::unique_ptr<Foo>>::value>*>
Foo* FooSmartPtrVector<SmartPtr>::add()
{
    auto uptr_foo = std::make_unique<Foo>();
    auto foo = uptr_foo.get();
    vec.emplace_back(std::move(uptr_foo));
    return foo;
}


// explicit instantiations of our templates
template class FooSmartPtrVector<observer_ptr>;
template class FooSmartPtrVector<std::unique_ptr>;
template Foo* FooSmartPtrVector<std::unique_ptr>::add();

bar.h

#include "FooSmartPtrVector.h"

struct Foo;

class Bar
{
public:
    Foo* getFromFooPtrView() const { return nullptr; }

private:
    bool isValid_;
    FooPtrVectorView observations_vector_;
};

Любая помощь приветствуется.

0 ответов

Другие вопросы по тегам