我希望能够将从DBMetaData
继承的对象的引用作为另一个类DBVar
的非类型模板参数传递:
#include <iostream>
class DBMetaData
{
public:
virtual const char *description( ) const = 0;
};
class DBMetaData_NT
: public DBMetaData
{
public:
const char *description( ) const
{ return "Useless description."; }
};
#if DO_WHAT_I_WANT
template< const DBMetaData &Metadata >
#else
template< typename MetadataType,
const MetadataType &Metadata >
#endif // DO_WHAT_I_WANT
class DBVar
{
public:
/// Descrição da variavel.
const char *description( ) const
{ return Metadata.description( ); }
};
DBMetaData_NT _md_u1;
#if DO_WHAT_I_WANT
DBVar< _md_u1 > _u1;
#else
DBVar< DBMetaData_NT, _md_u1 > _u1;
#endif // DO_WHAT_I_WANT
int main( )
{
std::cout << "_md_u1.description( ) = " << _md_u1.description( ) << std::endl;
std::cout << "_u1.description( ) = " << _u1.description( ) << std::endl;
return 0;
}
我可以编译并运行上面的示例但是我需要明确指定继承的类型。
如果我尝试编译它定义DO_WHAT_I_WANT
(我想将类型DBMetaData
的引用 - 或指针 - 传递给任何继承类的对象),我得到错误:
templ_inh_arg.cpp:36:15: error: could not convert template argument ‘_md_u1’ to ‘const DBMetaData&’
templ_inh_arg.cpp:36:20: error: invalid type in declaration before ‘;’ token
为什么我无法传递_u1
DBMetaData_NT
类型,DBMetaData
继承自DBVar< _md_u1 > _u1;
作为#include <iostream>
class DBMetaData
{
public:
/// Descrição da variavel.
virtual const char *description( ) const = 0;
};
class DBMetaData_NT
: public DBMetaData
{
public:
const char *description( ) const
{ return "Useless description."; }
};
typedef const DBMetaData &( *metadata )( );
template< metadata Metadata >
class DBVar
{
public:
/// Descrição da variavel.
const char *description( ) const
{ return Metadata( ).description( ); }
};
const DBMetaData & _md_u1_metadata( )
{
static const DBMetaData_NT _md_u1;
return _md_u1;
}
DBVar< _md_u1_metadata > _u1;
int main( )
{
std::cout << "_md_u1_metadata( ).description( ) = " << _md_u1_metadata( ).description( ) << std::endl;
std::cout << "_u1.description( ) = " << _u1.description( ) << std::endl;
return 0;
}
的参数?
有没有办法得到我想要的东西?
谢谢!
编辑:
用@ecatmur建议的函数指针替换模板参数解决了我的问题,我必须注意,我的代码更易读。
{{1}}
答案 0 :(得分:4)
不幸的是没有。根据14.3.2 模板非类型参数,第1段:
非类型,非模板模板参数的 template-argument 应为以下之一:[...]
- 一个常量表达式,用于指定具有静态存储持续时间[...]的对象的地址,表示(忽略括号)为
&
id-expression ,但{{如果相应的 template-parameter 是参考,则应省略1 ...}。
根据相同部分的第5段,不允许派生到基本的转化:
- 对于对象类型引用的非类型模板参数,不适用任何转换。引用引用的类型可能比 template-argument 的(否则相同)类型更符合cv。 template-parameter 直接绑定到 template-argument ,它应该是左值。
这也意味着不允许使用强制转换,因为它不是[&
] id-expression 的形式,并且不会产生左值。
根据您要完成的任务,您可以通过手动模拟多态性来获得类似的结果,例如:将&
初始化为函数的返回值,该函数设置适当的vtable指针或表。
答案 1 :(得分:1)
您可以使用C ++ 11的decltype
和以下宏来实现:
#define DBVAR(metadata) DBVar<decltype(metadata), metadata>
现在,定义一个变量:
DBVAR(_md_u1) _u1;
希望这有帮助。
编辑:说实话,我不喜欢你的做法。我宁愿选择静态元数据成员函数或基于非模板的多态性。