【发布时间】:2019-11-16 17:39:11
【问题描述】:
所以我一直在编写自己的 unique_ptr 类,我必须以与处理其他类型不同的方式处理数组。
template <typename TYPE, bool _arr = std::is_array<TYPE>::value>
class scoped_ptr final {
private:
typedef std::remove_extent_t<TYPE> gen;
gen* m_data;
public:
//some methods
void reset();
};
template<typename TYPE ,bool _arr>
inline void scoped_ptr<TYPE, _arr>::reset()
{
//some code...
}
问题是我希望重置方法仅适用于非数组分配,当使用 std::enable_if 时出现错误:“无法在类模板成员的声明中指定默认模板参数在其类之外”尽管代码仍在编译
template<typename TYPE ,bool _arr>
class scoped_ptr final {
public:
template<typename = typename std::enable_if<!_arr>::type>
void reset();
};
template<typename TYPE ,bool _arr>
template<typename = typename std::enable_if<!_arr>::type>
inline void scoped_ptr<TYPE, _arr>::reset()
{
}
我也试过这个,但也报错:“模板参数列表必须匹配参数列表”
template<typename TYPE ,bool _arr>
inline void scoped_ptr<TYPE, false>::reset()
{
}
有人知道如何为数组禁用此方法吗?我知道我可以专门化 scoped_ptr 类,但我想避免代码重复。有什么办法吗?
编辑:
阅读回复后,我将代码更改为:
template <typename TYPE, bool is_arr = std::is_array<TYPE>::value>
class scoped_ptr final {
private:
typedef std::remove_extent_t<TYPE> gen;
gen* m_data;
public:
//Some methods
template<bool _arr = is_arr, typename = typename std::enable_if<!_arr>::type>
void reset();
};
template<typename TYPE, bool is_arr>
template<bool, typename>
inline void scoped_ptr<TYPE, is_arr>::reset()
{
}
代码编译没有错误,直到我尝试调用该方法:
int main() {
scoped_ptr<int> ptr = new int;
ptr.reset();
}
当我收到错误消息时:“void scoped_ptr«int,false»::reset(void): could not deduc template argument for «unnamed-symbol»”
但如果我在类中编写实现,错误就会消失。我该如何解决这个问题?
【问题讨论】:
-
尝试将
template<bool, typename>替换为template<bool _arr, typename>。看起来像是 Microsoft 编译器中的错误。 -
哇,这对所有事情都有很大帮助,我还应该注意到我正在使用 Visual Studio 19。这个错误是否总是在这种情况下发生?我应该注意什么?
-
这些错误非常难以预测,并且没有通用的方法来避免它们以及如何修复它们。谈到模板,我在 MSVC 中看到过很多模板。我建议尝试另一个编译器(例如 gcc - 请参阅example),如果它编译代码,请修改它以使其与 MSVC 一起使用。添加冗余参数名称纯粹是我的猜测。