C++ 显式模板实例化与SFINAE

C++ 显式模板实例化与SFINAE,c++,c++11,templates,sfinae,explicit-instantiation,C++,C++11,Templates,Sfinae,Explicit Instantiation,我得到了一个编译错误,很明显我做错了什么,但我不知道如何修复它,也不知道是否有可能有显式的实例化和SFINAE。 可再现的示例是最小的,因此可能没有完全意义,但本质上有一个类似向量的类,可以实例化为unique_ptr或observer_ptr。 SFINAE部分仅允许添加功能仅对唯一的ptr可用 我在那里得到了一个定义编译失败。看起来,如果Bar有一个FooPtrVectorView,那么我会得到一个编译错误。如果我不给它下定义,那么一切都是好的。如果我只是在函数中使用fooptRVeCorV

我得到了一个编译错误,很明显我做错了什么,但我不知道如何修复它,也不知道是否有可能有显式的实例化和SFINAE。 可再现的示例是最小的,因此可能没有完全意义,但本质上有一个类似向量的类,可以实例化为unique_ptr或observer_ptr。 SFINAE部分仅允许添加功能仅对唯一的ptr可用

我在那里得到了一个定义编译失败。看起来,如果Bar有一个FooPtrVectorView,那么我会得到一个编译错误。如果我不给它下定义,那么一切都是好的。如果我只是在函数中使用fooptRVeCorView(而不是Bar的一部分),那么就没有问题了

msvc的编译器错误为 错误C3190:具有提供的模板参数的“Foo*foosmartprvector::add(void)”不是“foosmartprvector”的任何成员函数的显式实例化

对于msvc用户,我有一个包含整个解决方案的zip文件,这可能会使它更简单

观察员

template<typename T>
class observer_ptr
{
};
foosmartprvector.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>;

非常感谢您的帮助。

您能将zip文件上传到其他地方吗?为gcc/clangHave编译良好您是否尝试过
模板Foo*foosmartprvector::add()?@kirbyfan64sos@Jarod42将很快尝试并报告您能否将zip上传到其他地方?为gcc/clangHave编译良好您是否尝试过
模板Foo*foosmartprvector::add()?@kirbyfan64sos@Jarod42将很快尝试并报告
#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>;
#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();
#include "FooSmartPtrVector.h"

struct Foo;

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

private:
    bool isValid_;
    FooPtrVectorView observations_vector_;
};