问题描述
我想以一种方式定义一个基本模板类,以便它采用可变参数模板参数,并为每个参数定义一个虚方法,其中参数是参数类型。
例如 Base 应该给我3个虚拟方法:
Foo(int)
, Foo(bool)
和 Foo(string)
。
模板< typename Param>
struct BaseSingle
{
virtual void Foo(Param){};
};
template< typename ... Params>
struct Base:public BaseSingle< Params> ...
{
};
不幸的是,Foo变得模糊。我不能得到使用BaseSingle< Params> :: Foo ...
语法工作。是否有办法?
我知道,或者,我可以递归地继承BaseSingle并传递剩余的参数。
这里是一个建议,需要精确的类型匹配:
#include< utility>
#include< typeinfo>
#include< string>
#include< iostream>
#include< cstdlib>
#include< memory>
#include< cxxabi.h>
using namespace std;
// GCC demangling - 功能不需要
string demangle(const char * mangled){
int status;
unique_ptr< char [],void(*)(void *)> result(
abi :: __ cxa_demangle(mangled,0,0,& status),free);
return result.get()? string(result.get()):ERROR;
}
template< typename Param>
struct BaseSingle {
virtual void BaseFoo(Param){
cout<< Hello from BaseSingle<
<< demangle(typeid(Param).name())
<< > :: BaseFoo< endl;
};
};
template< typename ... Params>
struct Base:public BaseSingle< Params> ... {
template< typename T> void Foo(T&& x){
this-> BaseSingle< T> :: BaseFoo(forward< T>(x));
}
};
int main(){
Base< string,int,bool> b;
b.Foo(1);
b.Foo(true);
b.Foo(string(ab));但是你自己的建议使用递归继承听起来更加优雅。
I want to define a base template class in a way so that it takes variadic template arguments and defines a virtual method for each argument, where the parameter is the argument type.
E.g. Base<int, bool, string>
should give me 3 virtual methods: Foo(int)
, Foo(bool)
, and Foo(string)
.
I tried the following:
template <typename Param>
struct BaseSingle
{
virtual void Foo(Param) {};
};
template <typename... Params>
struct Base : public BaseSingle<Params>...
{
};
Unfortunately, Foo becomes ambiguous. I can't get the using BaseSingle<Params>::Foo...
syntax to work. Is there a way?
I know that, alternatively, I can recursively inherit from BaseSingle and pass in the remaining params. Are there perf implications of that?
解决方案 Here is a suggestion that requires exact type matching:
#include <utility>
#include <typeinfo>
#include <string>
#include <iostream>
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
using namespace std;
// GCC demangling -- not required for functionality
string demangle(const char* mangled) {
int status;
unique_ptr<char[], void (*)(void*)> result(
abi::__cxa_demangle(mangled, 0, 0, &status), free);
return result.get() ? string(result.get()) : "ERROR";
}
template<typename Param>
struct BaseSingle {
virtual void BaseFoo(Param) {
cout << "Hello from BaseSingle<"
<< demangle(typeid(Param).name())
<< ">::BaseFoo" << endl;
};
};
template<typename... Params>
struct Base : public BaseSingle<Params>... {
template<typename T> void Foo(T&& x) {
this->BaseSingle<T>::BaseFoo(forward<T>(x));
}
};
int main() {
Base<string, int, bool> b;
b.Foo(1);
b.Foo(true);
b.Foo(string("ab"));
}
But IMO your own suggestion using recursive inheritance sounds more elegant.
这篇关于使用可变参数模板中的参数定义多个方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!