这是 gcc 过载分辨率中的错误吗?
Is this an error in gcc's overload resolution?
我正在编写一个资源管理类,名为Wraiiper
。最终目标是能够编写类似的东西
Wraiiper wr(new ClassA(), destroyA); // cleanup with destroyA
wr.push_back(new ClassB()); // cleanup with delete
所以它基本上是动态大小的,接受任何类型,并使用delete
或自定义解除定位器进行删除。我想它所做的工作与std::vector<boost:any>
在插入到各种元素的唯一指针时所做的相同。代码(coliru链接)遵循
#include <iostream>
#include <algorithm>
#include <vector>
namespace dpol
{ // destruction policies
template<typename Func>
struct Destruction
{
Func finalize;
Destruction(Func f) : finalize(f)
{
}
template<typename T>
void apply(T* data)
{
if (data) finalize(data);
}
};
template<>
struct Destruction<void>
{
template<typename T>
void apply(T* data)
{
delete data;
}
};
} // destruction policies
class Wraiiper
{
struct ResourceConcept
{
virtual ~ResourceConcept() {}
virtual void* get() = 0;
};
template<typename T, typename Func>
struct ResourceModel : ResourceConcept, dpol::Destruction<Func>
{
T* data;
ResourceModel(T* data)
: dpol::Destruction<Func>()
, data(data)
{ // a. One arg constructor
}
ResourceModel(T* data, Func f)
: dpol::Destruction<Func>(f)
, data(data)
{ // b. Two args constructor
}
~ResourceModel()
{
dpol::Destruction<Func>::apply(data);
}
void* get()
{
return data;
}
};
std::vector<ResourceConcept*> resource;
public:
template<typename T, typename Func>
Wraiiper(T* data, Func f)
{
resource.push_back(new ResourceModel<T, Func>(data, f));
}
template<typename T>
Wraiiper(T* data)
{
resource.push_back(new ResourceModel<T, void>(data));
}
~Wraiiper()
{
while (!resource.empty())
{
delete resource.back();
resource.pop_back();
}
}
template<typename T, typename Func>
T* push_back(T* data, Func f)
{
resource.push_back(new ResourceModel<T, Func>(data, f));
return get<T*>(resource.size()-1);
}
template<typename T>
T* push_back(T* data)
{
resource.push_back(new ResourceModel<T, void>(data));
return get<T*>(resource.size()-1);
}
template<typename T>
T get(std::size_t i = 0)
{
return (T)resource.at(0)->get();
}
};
struct A
{
int val;
A(int x) : val(x) {}
};
void dela(A *arg) { delete arg; }
int main()
{
Wraiiper wr(new A(2), dela); // compiles fine
Wraiiper wr2(new double); // error !
return 0;
}
问题
以下错误困扰着我
main.cpp:在"structWraiiper::ResourceModel"的实例化中:
main.cpp:79:7:从'Wraiiper::Wraiiper(T*)[withT=double]'中需要
main.cpp:121:28:从这里开始需要
main.cpp:51:9:错误:无效的参数类型"void"
ResourceModel(T* data, Func f) ^
main.cpp:51:9:错误:在声明"Wraiiper::ResourceModel::ResourceModel(T*,Func)"中
我的论点是,在实例化Wraiiper::ResourceModel<double, void>
时应该选择带有一个自变量ResourceModel(T* data)
的构造函数(a),因为我显式地用一个自变量调用它
这里发生了什么,为什么会出现错误,我该如何克服它?
FWIW此操作在Visual Studio 2012 中也失败(相同错误)
我的论点是,在实例化Wraiiper::ResourceModel时,应该选择带有一个参数ResourceModel(T*data)的构造函数(a),因为我用一个参数显式调用它
调用函数不是问题所在;实例化ResourceModel<double, void>
是。您可能没有调用那个有问题的函数,但它在实例化时仍然必须在语义上有效:
[C++11: 14.7.1/1]:
[..]类模板专门化的隐式实例化导致声明的隐式实例,而不是类成员函数、成员类、作用域成员枚举、静态数据成员和成员模板的定义或默认参数的隐式实化[..]
…并且只要它尝试采用double*
和void
,则不满足该标准。
Clang的诊断输出使这一点稍微清晰:
clang++ -std=c++11 -O2 -pedantic -pthread main.cpp && ./a.out main.cpp:51:37: error: argument may not have 'void' type ResourceModel(T* data, Func f) ^ main.cpp:79:30: note: in instantiation of template class 'Wraiiper::ResourceModel<double, void>' requested here resource.push_back(new ResourceModel<T, void>(data)); ^ main.cpp:121:14: note: in instantiation of function template specialization 'Wraiiper::Wraiiper<double>' requested here Wraiiper wr2(new double); // error ! ^ 1 error generated.
您可以使用std::enable_if
禁用它。否则,我想你需要专门研究ResourceModel
的<..., void>
病例。另一种选择是将一个奇异函数发送到ResourceModel
中,而不是根本不发送,尽管您仍然需要为其选择一个可通过的类型
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- QScreen geometry()api为分辨率2736 x 1824和2560 x 1600提供了错误的值
- C 模板功能过载分辨率错误
- 这是 gcc 过载分辨率中的错误吗?
- Linux中的QPrinter分辨率错误
- 可变模板分辨率在VS2013 -错误C3520