可变模板构造函数不接受 x 参数

马蒂亚斯

对于模板化类的内部模板化结构,我想要一个可变参数模板化构造函数。不幸的是,构造函数(参见下面的第一个构造函数)是不够的:如果我只使用那个构造函数,我会得到 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...));
    ...
}

对于像boolas 可变参数这样的原语,一切正常。

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
甜甜的

需要注意的一件事(这可能是也可能不是问题的最终原因)是您在模板参数转发方面做得并不正确。例如,在情况下你传递一个ID3D11Device2DerivedResourceT可能构造函数(由非可变参数的构造函数的署名判定)预计参考-但是,因为模板的方式演绎的作品,它实际上会得到一个副本,而不是(如果确实此甚至是允许的 - 如果不是它就不会编译)。

要纠正此问题,您需要使用标准转发配方,它允许传递传递参数的正确 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调用中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

可变参数模板函数接受lambda

编写可变参数模板构造函数

Scrapy-TypeError:此构造函数不接受任何参数

unittest- TypeError:此构造函数不接受任何参数

我的构造函数方法不接受参数(directX / windows)

为什么 C++ 可变参数模板不接受 iostream 值作为参数?

函数不接受任何参数

如果构造函数不接受任何输入参数,则使用显式构造函数?

GNU Parallel不接受可变的python参数

构造函数接受参数时如何实例化模板类

可变参数模板构造函数优先级

通过可变参数模板的C ++ 11构造函数继承

限制可变参数模板类中的构造函数访问

可变参数模板递归构造函数问题

以模板化类作为参数的可变类构造函数

可变参数函数模板接受任何指针(指向变量,函数,成员函数等)作为参数

为每个可变参数模板参数调用函数,并将结果作为构造函数参数传递

通过转发构造函数参数,基于可变参数模板构造一个mixin

带有可变参数模板构造函数的推导指南和可变参数类模板-参数包长度不匹配

无法在Scala方法中使用主要构造函数:键入“不接受参数”

SFINAE可变参数构造函数

不接受任何参数解析的高阶函数

PHP调用Javascript函数不接受参数

python decorator不接受函数的参数

仅定义默认构造函数时,专用模板接受构造函数参数

我的可变参数模板构造函数隐藏了复制构造函数,防止类被复制

C ++-通过enable_if_t推导参数包(可变模板)构造函数和复制构造函数

值包装器的可变参数模板构造函数的类构造函数优先级

为什么可变参数模板构造函数比复制构造函数更好地匹配?