Für eine innere Vorlagenstruktur einer Vorlagenklasse möchte ich einen variablen Vorlagenkonstruktor haben. Leider reicht der Konstruktor (siehe erster Konstruktor unten) nicht aus: Wenn ich nur diesen Konstruktor verwende, erhalte ich C2260-Compilerfehler, die angeben, dass die Konstruktorfunktion nicht 3, 4 oder 5 Argumente benötigt. Auf der anderen Seite funktioniert alles, indem Sie drei weitere Konstruktoren hinzufügen (siehe die restlichen Konstruktoren unten), wie beabsichtigt.Variadischer Vorlagenkonstruktor akzeptiert keine X-Argumente
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) {}
...
}
}
ist Der Konstruktor wie folgt aufgerufen:
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...));
...
}
Für eine primitive wie ein bool
als variadische Argument, alles funktioniert.
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
Wo die Leitung 37 an den Konstruktor Anruf entspricht (new ResourcePoolEntry<DerivedResourceT>(*this, key, args...));
im Beispiel oben)
Was mache ich falsch? (Compiler MSVC++ 14.0)
Minimal Beispiel:
#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);
}
Fehler:
Severity Code Description Line Suppression State
Error C2661 'ResourcePool<char,A>::ResourcePoolEntry<DerivedResourceT>::ResourcePoolEntry': no overloaded function takes 3 arguments 66
Liefern tatsächlichen Fehlertext. In tatsächlichen Zeilen. Stellen Sie idealerweise ein [MCVE] bereit, das den Fehler generiert. Möglicherweise müssen Sie Ihren Code ändern, um unwichtige Inhalte zu entfernen. Es ist sehr schwierig herauszufinden, ob Sie wichtige Dinge in Ihren "Details entfernen" beseitigt haben, und es wird zu einem Schmerz, Ihre Gedanken zu lesen. Ich werde bemerken, dass Ihr Variantkern die Dinge * nach Wert * nimmt, während Ihre Manuellen sie durch eine Mischung aus Referenz- und Konstantenbezug nehmen. – Yakk
@Yakk Nimmt mein variadic ctor nicht alles auf, wie ich es passiere? – Matthias
Es dauert Dinge von Wert. Dies könnte Probleme verursachen. Ich kann es nicht sagen, weil Sie die tatsächlichen Build-Fehler nicht erstellt haben und ich nicht jeden Typ kenne, mit dem Sie arbeiten. Nochmal [MCVE], und tatsächliche Fehler, oder deine Frage ist schlecht. – Yakk