テンプレートクラスの内側のテンプレート構造体については、バリデーションテンプレートコンストラクタが必要です。残念ながら、コンストラクター(以下の最初のコンストラクターを参照)で十分ではありません。そのコンストラクターのみを使用すると、コンストラクター関数が3つ、4つまたは5つの引数を取らないことを示すC2260コンパイラー・エラーが発生します。一方、別の3つのコンストラクタを追加することで明示的にすべてを明示的にする(以下のコンストラクタの残りを参照してください)。コンストラクタは、このように呼ばれてVariadicのテンプレートコンストラクタはx引数を受け取りません
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) {}
...
}
}
:bool
として可変長引数のようなプリミティブについて
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...));
...
}
、すべてが正常に動作します。ライン37は、私が間違っているのは何
(上記の例ではnew ResourcePoolEntry<DerivedResourceT>(*this, key, args...));
)コンストラクタ呼び出しに対応
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
? (コンパイラ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
実際のエラーテキストを提供しています。実際の行について。理想的には、エラーを生成する[MCVE]を提供してください。これは、無関係なものを削除するためにコードを変更する必要があるかもしれません。あなたが「細部を取り除く」に重要なものを取り除いたかどうかを知ることは非常に難しく、あなたの心を読むのは苦痛になります。私はあなたのバリデーションされたctorが値*で物事を取るのに対し、あなたのマニュアルは参照とconst参照が混在しています。 – Yakk
@ Yakk私のバリデーションは、私がそれを渡す方法ですべてを取っていませんか? – Matthias
物事は価値があります。これは問題を引き起こす可能性があります。実際にビルドエラーが発生していないため、作業しているすべてのタイプがわからないため、わかりません。再度[MCVE]と実際のエラー、またはあなたの質問は悪いものです。 – Yakk