gpt4 book ai didi

c++ - Variadic 模板化构造函数不接受 x 个参数

转载 作者:行者123 更新时间:2023-11-30 03:33:25 25 4
gpt4 key购买 nike

对于模板类的内部模板结构,我想要一个可变参数模板构造函数。不幸的是,构造函数(见下面的第一个构造函数)是不够的:如果我只使用那个构造函数,我会得到 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:\users\matthias\documents\visual studio 2015\projects\mage\mage\mage\src\resource\resource_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 构造函数可能(根据非可变构造函数的签名判断)需要一个引用 - 但是因为模板推导的工作方式实际上会得到一个拷贝(如果确实允许,则不会编译)。

要纠正此问题,您需要使用标准转发配方,它允许传递传递参数的正确左值或右值,其中包括正确转发引用:

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++ - Variadic 模板化构造函数不接受 x 个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42954380/

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