可变参数模板化构造函数不接受 x 参数
Variadic templated constructor does not take x arguments
对于模板化类的内部模板化结构,我想要一个可变参数化构造函数。不幸的是,构造函数(请参阅下面的第一个构造函数(是不够的:如果我只使用该构造函数,我会收到 C2260 编译器错误,指出构造函数不接受 3、4 或 5 个参数。另一方面,通过添加另外三个构造函数(请参阅下面的其余构造函数(使所有内容都显式化,按预期工作。
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) {}
...
}
}
构造函数的调用方式如下:
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...));
...
}
对于像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:usersmatthiasdocumentsvisual studio 2015projectsmagemagemagesrcresourceresource_pool.tpp 37
其中第 37 行对应于构造函数调用(在上面的示例中new ResourcePoolEntry< DerivedResourceT >(*this, key, args...));
(
我做错了什么?(编译器 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);
}
错误:
Severity Code Description Line Suppression State
Error C2661 'ResourcePool<char,A>::ResourcePoolEntry<DerivedResourceT>::ResourcePoolEntry': no overloaded function takes 3 arguments 66
需要注意的一件事(这可能是也可能不是问题的最终原因(是您在模板参数转发方面做得不对。例如,在你传递ID3D11Device2
的情况下,你的DerivedResourceT
构造函数可能(从你的非可变参数构造函数的签名判断(需要一个引用 - 但是由于模板推导的工作方式,它实际上会得到一个副本(如果这确实是允许的 - 如果不是,它不会编译(。
要更正此问题,您需要使用标准转发配方,它允许传递传递参数的正确 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) {}
在上面,请注意参数类型中的&&
args...
和std::forward
调用。
相关文章:
- C++:使用运算符 = 调用多参数构造函数
- 通过零参数构造函数创建的 glm::mat4 应该包含哪些值?
- 好奇的混合与可变参数构造函数
- 具有默认值的单个参数构造函数是否与默认构造函数相同?
- 为什么我们需要创建一个单参数构造函数来使用临时的无名称对象
- 在可变参数构造函数中初始化常量数组
- C++ 显式多参数构造函数歧义
- 零一参数构造函数
- 可变参数构造函数中的 SFINAE
- 当没有显式关键字与单参数构造函数一起使用时,编译器可以发出警告
- 可变参数类模板和可变参数构造函数
- 确保模板参数类型与其可变参数构造函数的类型匹配
- C++默认参数构造函数与内联初始化优先级
- 如何在 c++ 中将包含复制构造函数的类的参数构造函数称为私有?
- 自动存储中没有无参数构造函数的类对象和异常
- 警告:用两个参数构造函数返回对象时,表达结果未使用
- 如何在C++中调用无参数构造函数
- 在 c++ 中具有多个参数构造函数的模板类存在问题
- 可变参数构造函数优先于用户提供的移动构造函数,除非默认
- 如何从可变参数构造函数参数构造任何对象?