Nehmen Sie zum Beispiel den folgenden Code:Wie Übergeben Vorlagen Vorlagenparameter zu Vorlagenklasse ohne den zugrunde liegenden Vorlagenparameter?
// Say I have this class defined in some other file
class Foo;
// This class will act as a wrapper for an integer map
// to function pointers, which will create type TFoo objects
// depending on the given input (in this case a "const char*"
template<class TFoo>
struct Bar
{
typedef TFoo foo_t;
typedef TFoo (*get_foo_f_t)(const char*);
typedef std::unordered_map<int, get_foo_f_t> foo_handler_map_t;
Bar(const foo_handler_map_t& handlers)
: handlers_(handlers)
{
}
~Bar()
{
}
const foo_handler_map_t& handlers_;
};
// Now, this class will receive an _object_ of type
// "const Bar<T>&", which will have an already initialized
// map of integers to function pointers, different
// functions will be called with different input values
// via the public method, "action()".
template<class TFoo, const Bar<TFoo>& CBar>
class Quux
{
public:
Quux()
: bar_(CBar)
{
}
~Quux()
{
}
TFoo action(int a, const char* x)
{
auto it = this->bar_.handlers_.find(a);
if (it == this->bar_.handlers_.end())
{
// no handler defined for int `a'
return TFoo();
}
// i.e. CBar.handlers_[a](x)
return it->second(x);
}
private:
const Bar<TFoo>& bar_;
};
// Here is how the map of integers to function pointers
// will be initialized...
static std::unordered_map<int, Foo (*)(const char*)> handlers
{
{ 0, _hdl_0 }, // _hdl_* functions defined in different file
{ 1, _hdl_1 },
{ 2, _hdl_2 }
};
// And then passed to a "const Bar<T>" type object here
const Bar<Foo> bar (handlers);
int main()
{
// --> HERE IS WHAT I WANT TO CHANGE <--
Quux<decltype(bar)::foo_t, bar> quux;
// -------------------------------------
// Example (trivial) use of the 'quux' object
std::cout << quux.action(0, "abc").baz() << std::endl;
std::cout << quux.action(1, "def").baz() << std::endl;
std::cout << quux.action(2, "ghi").baz() << std::endl;
return 0;
}
Beachten Sie, dass die ‚Quux‘ Klasse nimmt zwei Template-Parameter - eine, die auch ein Template-Parameter für die ‚Bar‘ Klasse ist, und ein Verweis auf eine Vorlage Objekt vom Typ const Bar<T>
, wobei T irgendeine Klasse ist, die mit 'Foo' in Beziehung steht. Ich möchte in der Lage sein, Folgendes zu tun statt:
Quux<bar> quux;
Hinweis: ‚bar‘ ist ein Objekt vom Typ Bar<Foo>
, aber es sollte auch jeder Bar<T>
Typ sein kann.
Ist das möglich? Ich dachte, dass vielleicht so etwas wie unten als eine schnelle Abhilfe verwendet werden könnte, aber ich kann nicht herausfinden, was anstelle von /* ??? */
zu setzen:
template<const Bar</* ??? */>& CBar>
using Nuff = Quux<decltype(CBar)::foo_t, CBar>
Nuff<bar> nuff;
EDIT
Ich bin einen Verweis auf ein Objekt an 'Quux' als Vorlagenparameter übergeben, weil das Kopieren ineffizient wäre (denke ich), anstatt eine Kopie des gesamten foo_handler_map_t
Objekts zu erstellen. Ich möchte nur in der Lage eine Reihe von Objekten des Typs zu haben const Bar<T>
, die global in einigen Namensraum definiert sind, und in der Lage Objekte ‚Quux‘ wie so zu initialisieren:
namespace blah
{
std::unordered_map<int, /* funcptr type 0 */> _funcmap_0 { ... }
std::unordered_map<int, /* funcptr type 1 */> _funcmap_1 { ... }
...
const Bar<Foo0> FSET0 (_funcmap_0);
const Bar<Foo1> FSET1 (_funcmap_1);
...
}
int main()
{
Quux<blah::FSET0> a;
Quux<blah::FSET1> b;
...
return 0;
}
... und ich weiß nicht möchte es als Konstruktorargument übergeben.
Was ist das 'template & CBAR>' ? Da Sie angeben, dass es kompiliert wird, denke ich, dass es genau wie ein Zeiger auf ein externes Objekt gültig ist. Aber was ist der Zweck hier, was versuchst du zu erreichen? –
Es wäre schön, wenn Sie Ihr Beispiel stark reduzieren können. Bitte geben Sie den minimalen Code an, den wir benötigen, um Ihre Frage zu stellen! – Klaus
Dies ist im aktuellen C++ nicht möglich, wird einmal möglich sein [n4469] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4469.html) wird angenommen. –