仅在两个成员都参数化后,模板模板参数才会出现构建错误
我试图传递一个模板模板参数,其参数是一个非类型值,其类型等于前一个模板参数的子类型(哇!这很难说,也很难读!),我尝试将结果加入单个参数化模板后出现一些构建错误。
我有以下代码(使用 g++ 4.4.1 和 -std=c++0x 编译得很好):
#include <iostream>
using namespace std;
enum class Labels { A , B };
template <Labels L>
struct LabelTypeMap {
typedef int type_t;
};
template<> struct LabelTypeMap<Labels::B> { typedef double type_t; };
template <bool Enable=true>
struct Hold
{
typedef Labels enum_t;
};
template <>
struct Hold<true>
{
typedef Labels enum_t;
};
template< typename Holder , template< typename Holder::enum_t > class typeMap , bool Enable >
struct Whatever
{
template < typename Holder::enum_t label >
void Operate(typename typeMap<label>::type_t parameter) {};
};
template< typename Holder , template< typename Holder::enum_t > class typeMap >
struct Whatever< Holder , typeMap , true > : public Holder
{
template < typename Holder::enum_t label >
void Operate(typename typeMap<label>::type_t parameter) { cout << "operate on " << parameter << endl; };
};
template < bool Enable >
struct Now {
typedef Hold<true> MyHold; // <----- check this out!
typedef Whatever< MyHold , LabelTypeMap , Enable > concrete_t;
};
int main() {
Now< true >::concrete_t obj;
obj.Operate< Labels::A >( 3.222222222222222222222 );
obj.Operate< Labels::B >( 3.2222222222222222222 );
};
但是,现在,看看 Now
模板:我有两个参数化的成员布尔值。然而,concrete_t
取决于封闭的 Now
模板的 bool 参数,而 MyHold
则不然。我想改变这一点,所以我用这个替换了 Now
声明:
template < bool Enable >
struct Now {
typedef Hold<Enable> MyHold; // <----- boom!
typedef Whatever< MyHold , LabelTypeMap , Enable > concrete_t;
};
但这给了我以下错误:
error: type/value mismatch at argument 2 in template parameter list for ‘template<class Holder, template<typename Holder::enum_t <anonymous> > class typeMap, bool Enable> struct Whatever’
error: expected a template of type ‘template<typename Holder::enum_t <anonymous> > class typeMap’, got ‘template<Labels L> struct LabelTypeMap’
我已经盯着这个声明足够长的时间了,我必须说我完全不明白为什么这个简单的更改会触发错误。有什么想法吗?
编辑:这是对问题的最小阐述,以(希望)使其更容易思考:
$ cat templatetemplate.cc
template <int i>
struct LabelTypeMap { typedef int type_t; };
template <bool>
struct Hold { typedef int type; };
template<typename Holder, template<typename Holder::type> class typeMap>
struct Whatever { };
template <bool Enable>
struct Now { typedef Whatever<Hold<ENABLE>, LabelTypeMap> concrete_t; };
Now<true>::concrete_t obj;
$ g++ -DENABLE=Enable -c templatetemplate.cc
templatetemplate.cc:11: error: type/value mismatch at argument 2 in template parameter list for ‘template<class Holder, template<typename Holder::type <anonymous> > class typeMap> struct Whatever’
templatetemplate.cc:11: error: expected a template of type ↵
‘template<typename Holder::type <anonymous> > class typeMap’, got ↵
‘template<int i> struct LabelTypeMap’
marcelo@macbookpro-1:~/play$
$ g++ -DENABLE=true -c templatetemplate.cc
(no error)
I am trying to pass a template template parameter whom its parameter is a non-type value of type equal to a subtype of a previous template parameter (whew! that was as hard to say as it is to read!), and i'm having some build errors after trying to join the results in a single parametrized templates.
I have the following code (which compiles just fine with g++ 4.4.1 and -std=c++0x):
#include <iostream>
using namespace std;
enum class Labels { A , B };
template <Labels L>
struct LabelTypeMap {
typedef int type_t;
};
template<> struct LabelTypeMap<Labels::B> { typedef double type_t; };
template <bool Enable=true>
struct Hold
{
typedef Labels enum_t;
};
template <>
struct Hold<true>
{
typedef Labels enum_t;
};
template< typename Holder , template< typename Holder::enum_t > class typeMap , bool Enable >
struct Whatever
{
template < typename Holder::enum_t label >
void Operate(typename typeMap<label>::type_t parameter) {};
};
template< typename Holder , template< typename Holder::enum_t > class typeMap >
struct Whatever< Holder , typeMap , true > : public Holder
{
template < typename Holder::enum_t label >
void Operate(typename typeMap<label>::type_t parameter) { cout << "operate on " << parameter << endl; };
};
template < bool Enable >
struct Now {
typedef Hold<true> MyHold; // <----- check this out!
typedef Whatever< MyHold , LabelTypeMap , Enable > concrete_t;
};
int main() {
Now< true >::concrete_t obj;
obj.Operate< Labels::A >( 3.222222222222222222222 );
obj.Operate< Labels::B >( 3.2222222222222222222 );
};
However, Now, look at the Now
template: I have two members that are parametrized by booleans. concrete_t
depends however on the bool parameter of the enclosing Now
template, while MyHold
does not. I want to change that, so i replace the Now
declaration with this one:
template < bool Enable >
struct Now {
typedef Hold<Enable> MyHold; // <----- boom!
typedef Whatever< MyHold , LabelTypeMap , Enable > concrete_t;
};
but this gives me the following errors:
error: type/value mismatch at argument 2 in template parameter list for ‘template<class Holder, template<typename Holder::enum_t <anonymous> > class typeMap, bool Enable> struct Whatever’
error: expected a template of type ‘template<typename Holder::enum_t <anonymous> > class typeMap’, got ‘template<Labels L> struct LabelTypeMap’
I've stared long enough at this and i must say that i completely fail to see why this simple change would trigger an error. any ideas?
EDIT: Here's a minimal exposition of the problem to (hopefully) make it easier to ponder:
$ cat templatetemplate.cc
template <int i>
struct LabelTypeMap { typedef int type_t; };
template <bool>
struct Hold { typedef int type; };
template<typename Holder, template<typename Holder::type> class typeMap>
struct Whatever { };
template <bool Enable>
struct Now { typedef Whatever<Hold<ENABLE>, LabelTypeMap> concrete_t; };
Now<true>::concrete_t obj;
$ g++ -DENABLE=Enable -c templatetemplate.cc
templatetemplate.cc:11: error: type/value mismatch at argument 2 in template parameter list for ‘template<class Holder, template<typename Holder::type <anonymous> > class typeMap> struct Whatever’
templatetemplate.cc:11: error: expected a template of type ↵
‘template<typename Holder::type <anonymous> > class typeMap’, got ↵
‘template<int i> struct LabelTypeMap’
marcelo@macbookpro-1:~/play$
$ g++ -DENABLE=true -c templatetemplate.cc
(no error)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个可以编译的解决方法,直到有人能够解决这个问题:
Here's a work-around that compiles, until someone can figure out the mess: