C++ 这是gcc'中的错误吗;什么是超负荷解决方案?
我正在编写一个资源管理类,名为C++ 这是gcc'中的错误吗;什么是超负荷解决方案?,c++,templates,C++,Templates,我正在编写一个资源管理类,名为wraiper。最终目标是能够写出以下内容 Wraiiper wr(new ClassA(), destroyA); // cleanup with destroyA wr.push_back(new ClassB()); // cleanup with delete 因此,它基本上是动态大小的,接受任何类型,并使用delete或自定义deallocator进行删除。如果我插入指向不同元素的唯一指针,我猜它所做的工作与std::vector所做
wraiper
。最终目标是能够写出以下内容
Wraiiper wr(new ClassA(), destroyA); // cleanup with destroyA
wr.push_back(new ClassB()); // cleanup with delete
因此,它基本上是动态大小的,接受任何类型,并使用delete
或自定义deallocator进行删除。如果我插入指向不同元素的唯一指针,我猜它所做的工作与std::vector所做的相同。代码()如下
main.cpp:51:9:错误:在声明“Wraiiper::ResourceModel::ResourceModel(T*,Func)”中
我的论点是,当实例化Wraiiper::ResourceModel
时,应该选择具有一个参数ResourceModel(T*data)
的构造函数(a),因为我显式地使用一个参数调用它
这里发生了什么,为什么会有错误,我怎样才能克服它
FWIW在Visual Studio 2012中也会失败(相同的错误)
我的论点是,在实例化Wraiiper::ResourceModel时,应该选择具有一个参数ResourceModel(T*data)的构造函数(a),因为我使用一个参数显式调用它
调用函数不是问题;正在实例化ResourceModel
。您可能没有调用该有问题的函数,但它在实例化时仍必须在语义上有效:
[C++11:14.7.1/1]:
[..]类模板专用化的隐式实例化会导致声明的隐式实例化,但不会导致类成员函数的定义或默认参数的隐式实例化、成员类、作用域成员枚举、,静态数据成员和成员模板;[……]
…而且只要它尝试采用double*
和void
,就不符合该标准
:
clang++-std=c++11-O2-pedantic-pthread main.cpp&./a.out
main.cpp:51:37:错误:参数可能没有“void”类型
资源模型(T*数据,函数f)
^
main.cpp:79:30:注意:在这里请求的模板类'Wraiiper::ResourceModel'的实例化中
资源。推回(新资源模型(数据));
^
main.cpp:121:14:注意:在函数模板专门化的实例化中,此处请求了'wraiper::wraiper'
Wraiiper wr2(新双人床);//错误!
^
生成1个错误。
如果,您可以使用
std::enable\u禁用此专门化。否则,我想您需要专门研究
案例的ResourceModel
。另一种方法是将单个函数发送到ResourceModel
中,而不是一个函数都不发送,尽管您仍然需要为它选择一个可通过的类型。使用它进行编译,将提供更好的错误消息。是的,这是有意义的。也许我会尝试将两个构造函数都模板化,然后让SFINAE隐式应用yperhaps提供一个引用标准,该标准说,如果类是,则成员函数的声明将实例化。好的,如果两个构造函数都模板化,则每次只实例化一个使用的构造函数,因此编译,thnx man
#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;
}
ResourceModel(T* data, Func f)
^
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.