[英]Variadic templated constructor does not take x arguments
For an inner templated struct of a templated class, I want to have a variadic templated constructor. 对于模板化类的内部模板化结构,我想要一个可变参数的模板化构造函数。 Unfortunately the constructor (see first constructor below) does not suffice: if I only use that constructor, I obtain C2260 compiler errors stating that the constructor function does not take 3, 4 or 5 arguments.
不幸的是,构造函数(请参见下面的第一个构造函数)不能满足要求:如果仅使用该构造函数,则会出现C2260编译器错误,指出构造函数没有3、4或5个参数。 On the other hand, making everything explicit by adding another three constructors (see remaining constructors below) works as intended.
另一方面,通过添加另外三个构造函数(请参阅下面的其余构造函数)使所有内容显式工作即可。
template< typename KeyT, typename ResourceT >
class ResourcePool {
...
template< typename DerivedResourceT >
struct ResourcePoolEntry final : public DerivedResourceT {
template< typename... ConstructorArgsT >
ResourcePoolEntry(ResourcePool< KeyT, ResourceT > &resource_pool,
KeyT resource_key, ConstructorArgsT... args)
: DerivedResourceT(args...), m_resource_pool(resource_pool), m_resource_key(resource_key) {}
ResourcePoolEntry(ResourcePool< KeyT, ResourceT > &resource_pool,
KeyT resource_key, ID3D11Device2 &x)
: DerivedResourceT(x), m_resource_pool(resource_pool), m_resource_key(resource_key) {}
ResourcePoolEntry(ResourcePool< KeyT, ResourceT > &resource_pool,
KeyT resource_key, ID3D11Device2 &x, const wstring &y)
: DerivedResourceT(x,y), m_resource_pool(resource_pool), m_resource_key(resource_key) {}
template < typename VertexT >
ResourcePoolEntry(ResourcePool< KeyT, ResourceT > &resource_pool,
KeyT resource_key, ID3D11Device2 &x, const wstring &y, const MeshDescriptor< VertexT > &z)
: DerivedResourceT(x, y, z), m_resource_pool(resource_pool), m_resource_key(resource_key) {}
...
}
}
The constructor is called like this: 构造函数的调用方式如下:
template< typename KeyT, typename ResourceT >
template< typename... ConstructorArgsT >
std::shared_ptr< ResourceT > ResourcePool< KeyT, ResourceT >::GetResource(KeyT key, ConstructorArgsT... args) {
return GetDerivedResource< ResourceT, ConstructorArgsT... >(key, args...);
}
template< typename KeyT, typename ResourceT >
template< typename DerivedResourceT, typename... ConstructorArgsT >
std::shared_ptr< ResourceT > ResourcePool< KeyT, ResourceT >::GetDerivedResource(KeyT key, ConstructorArgsT... args) {
...
auto new_resource = std::shared_ptr< ResourcePoolEntry< DerivedResourceT > >(
new ResourcePoolEntry< DerivedResourceT >(*this, key, args...));
...
}
For a primitive like a bool
as variadic argument, everything works fine. 对于像
bool
这样的原始参数,一切都很好。
Severity Code Description Project File Line Suppression State
Error C2660 'mage::ResourcePool<std::wstring,mage::VertexShader>::ResourcePoolEntry<DerivedResourceT>::ResourcePoolEntry': function does not take 3 arguments MAGE c:\users\matthias\documents\visual studio 2015\projects\mage\mage\mage\src\resource\resource_pool.tpp 37
Where line 37 corresponds to the constructor call ( new ResourcePoolEntry< DerivedResourceT >(*this, key, args...));
其中第37行对应于构造函数调用(
new ResourcePoolEntry< DerivedResourceT >(*this, key, args...));
in the example above) 在上面的示例中)
What am I doing wrong? 我究竟做错了什么? (Compiler MSVC++ 14.0)
(编译器MSVC ++ 14.0)
#include <memory>
#include <map>
template < typename T >
using SharedPtr = std::shared_ptr< T >;
template < typename T >
using WeakPtr = std::weak_ptr< T >;
template< typename KeyT, typename ResourceT >
using ResourceMap = std::map< KeyT, WeakPtr< ResourceT > >;
template< typename KeyT, typename ResourceT >
class ResourcePool {
public:
template< typename... ConstructorArgsT >
SharedPtr< ResourceT > GetResource(KeyT key, ConstructorArgsT... args);
template< typename DerivedResourceT, typename... ConstructorArgsT >
SharedPtr< ResourceT > GetDerivedResource(KeyT key, ConstructorArgsT... args);
private:
ResourceMap< KeyT, ResourceT > m_resource_map;
template< typename DerivedResourceT >
struct ResourcePoolEntry final : public DerivedResourceT {
public:
template< typename... ConstructorArgsT >
ResourcePoolEntry(ResourcePool< KeyT, ResourceT > &resource_pool,
KeyT resource_key, ConstructorArgsT... args)
: DerivedResourceT(args...), m_resource_pool(resource_pool), m_resource_key(resource_key) {}
private:
ResourcePool< KeyT, ResourceT > &m_resource_pool;
KeyT m_resource_key;
};
};
template< typename KeyT, typename ResourceT >
template< typename... ConstructorArgsT >
SharedPtr< ResourceT > ResourcePool< KeyT, ResourceT >::GetResource(KeyT key, ConstructorArgsT... args) {
return GetDerivedResource< ResourceT, ConstructorArgsT... >(key, args...);
}
template< typename KeyT, typename ResourceT >
template< typename DerivedResourceT, typename... ConstructorArgsT >
SharedPtr< ResourceT > ResourcePool< KeyT, ResourceT >::GetDerivedResource(KeyT key, ConstructorArgsT... args) {
auto it = m_resource_map.find(key);
if (it != m_resource_map.end()) {
auto resource = it->second.lock();
if (resource) {
return resource;
}
else {
m_resource_map.erase(it);
}
}
auto new_resource = SharedPtr< ResourcePoolEntry< DerivedResourceT > >(
new ResourcePoolEntry< DerivedResourceT >(*this, key, args...));
m_resource_map[key] = new_resource;
return new_resource;
}
#include <d3d11_2.h>
struct A {
};
struct B : public A {
B(ID3D11Device &device) : A() {}
};
const D3D_FEATURE_LEVEL g_feature_levels[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0
};
int main() {
ID3D11Device *device;
ID3D11DeviceContext *device_context;
D3D_FEATURE_LEVEL feature_level;
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0,
g_feature_levels, _countof(g_feature_levels), D3D11_SDK_VERSION,
&device, &feature_level, &device_context
);
ResourcePool< char, A > *pool = new ResourcePool< char, A >();
//pool->template GetResource< int & >('a');
pool->template GetDerivedResource< B, ID3D11Device & >('b', *device);
}
Error : 错误 :
Severity Code Description Line Suppression State
Error C2661 'ResourcePool<char,A>::ResourcePoolEntry<DerivedResourceT>::ResourcePoolEntry': no overloaded function takes 3 arguments 66
One thing to note (which may or may not be the ultimate cause of your problem) is that you're not doing quite the right thing with your template parameter forwarding. 需要注意的一件事(可能是导致问题的最终原因,也可能不是导致问题的最终原因)是,您在模板参数转发方面做的不够正确。 For example, in the case where you're passing an
ID3D11Device2
your DerivedResourceT
constructor probably (judging by the signature of your non-variadic constructors) expects a reference - however because of the way template deduction works it will actually get a copy instead (if indeed this is even permissable - if not it would not compile). 例如,在传递
ID3D11Device2
的情况下,您的DerivedResourceT
构造函数(通过非可变构造函数的签名判断)可能需要引用-但是由于模板推导的工作方式,它实际上将获得一个副本(如果实际上,这甚至是允许的-否则将无法编译)。
To correct this, you need to use the standard forwarding recipe, which allows the correct l- or r-valueness of a passed parameter to be passed on, which includes correctly forwarding references: 要更正此问题,您需要使用标准转发配方,该转发配方允许传递所传递参数的正确的l值或r值,其中包括正确的转发引用:
template< typename... ConstructorArgsT >
ResourcePoolEntry(ResourcePool< KeyT, ResourceT > &resource_pool,
KeyT resource_key, ConstructorArgsT&&... args)
: DerivedResourceT(std::forward<ConstructorArgsT>(args)...), m_resource_pool(resource_pool), m_resource_key(resource_key) {}
In the above, note the &&
in the parameter type of args...
and the std::forward
call. 在上面的代码中,请注意参数类型
args...
的&&
和std::forward
调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.