我收到一个编译错误,很明显我做错了什么,但我不确定如何修复它,也不知道是否可以进行显式实例化和 SFINAE。可重现的示例是最小的,因此它可能不完全有意义,但本质上存在一个可以为 unique_ptr 或observer_ptr 实例化的向量类。SFINAE 部分仅允许 add 函数仅对 unique_ptr 可用。
我在那里定义了CompilationFail。似乎如果 Bar 有一个 FooPtrVectorView 那么我得到一个编译错误。如果我不定义它,那么一切都很好。如果我只是在一个函数(而不是 Bar 的一部分)中使用 FooPtrVectorView 就没有问题。
msvc 的编译器错误是错误 C3190: 'Foo *FooSmartPtrVector::add(void)' with the provided template arguments is not the explicit instantiation of any member function of 'FooSmartPtrVector'
对于 msvc 用户,我有一个包含整个解决方案的 zip 文件,这可能会使它更容易https://app.box.com/s/nzbgvxo58u4jmiw50o1hlh28yfyxo1d1
观察者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();
酒吧.h
#include "FooSmartPtrVector.h"
struct Foo;
class Bar
{
public:
Foo* getFromFooPtrView() const { return nullptr; }
private:
bool isValid_;
FooPtrVectorView observations_vector_;
};
任何帮助表示赞赏。