gpt4 book ai didi

c++ - 这是 gcc 的重载解析中的错误吗?

转载 作者:行者123 更新时间:2023-11-28 06:36:39 25 4
gpt4 key购买 nike

我正在编写一个资源管理类,名为 Wraiiper .最终目标是能够写出像

这样的东西
Wraiiper wr(new ClassA(), destroyA); // cleanup with destroyA 
wr.push_back(new ClassB()); // cleanup with delete

所以它基本上是动态大小的,接受任何类型,并使用 delete 删除或自定义释放器。我猜它和 std::vector<boost:any> 做同样的工作如果我插入指向各种元素的唯一指针会怎样。代码( coliru link )如下

#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: In instantiation of 'struct Wraiiper::ResourceModel':

main.cpp:79:7: required from 'Wraiiper::Wraiiper(T*) [with T = double]'

main.cpp:121:28: required from here

main.cpp:51:9: error: invalid parameter type 'void'

    ResourceModel(T* data, Func f)

^

main.cpp:51:9: error: in declaration 'Wraiiper::ResourceModel::ResourceModel(T*, Func)'

我的观点是构造函数 (a) 带有一个参数 ResourceModel(T* data)实例化时应该选择Wraiiper::ResourceModel<double, void>因为我明确地用一个参数调用它

这里发生了什么,为什么会出现错误,我该如何克服它?

FWIW 这在 Visual Studio 2012 中也失败(同样的错误)

最佳答案

My argument is that the constructor (a) with one argument ResourceModel(T* data) should be selected when instantiating Wraiiper::ResourceModel since I explicitly call it with one argument

调用函数没有问题;实例化 ResourceModel<double, void>是。您可能不会调用那个有问题的函数,但它在实例化时仍然必须在语义上有效:

[C++11: 14.7.1/1]: [..] The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, scoped member enumerations, static data members and member templates; [..]

...只要它尝试使用 double*和一个 void , 不满足该标准。

Clang's diagnostic output makes this marginally clearer :

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而不是根本没有,尽管您仍然需要为它选择一个可以通过的类型。

关于c++ - 这是 gcc 的重载解析中的错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26672776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com