首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何转换为正确的祖先类,以便定义模板专门化

如何转换为正确的祖先类,以便定义模板专门化
EN

Stack Overflow用户
提问于 2014-03-09 11:25:35
回答 2查看 176关注 0票数 1

我得到一个编译器错误

代码语言:javascript
复制
../main.cpp: In function ‘int main()’:
../main.cpp:38:16: error: no matching function for call to ‘do_stuff(x&)’
../main.cpp:38:16: note: candidate is:
../main.cpp:30:6: note: template<class M> void do_stuff(M, typename a<M>::is_valid_type)
make: *** [main.o] Error 1

以获取以下代码:

代码语言:javascript
复制
template<typename S>
class a
{
};

template<typename T>
class b
{
};

class x: public b<int>
{
};

template<typename T>
class a<b<T> >
{
public:
  typedef void* is_valid_type;
};

template<typename M>
void do_stuff(M thing, typename a<M>::is_valid_type t = 0)
{
  a<M> whatevs;
}

int main()
{
  x my_x;
  do_stuff(my_x);
}

在这里,我想隐式地将x类型的对象强制转换为定义了a::is_valid_type的某个超类M(在本例中为b)。但这似乎行不通。我该怎么做呢?

(不使用任何c++-11构造)

EN

回答 2

Stack Overflow用户

发布于 2014-03-09 12:51:48

如果我正确理解了您的问题,编译器将不会使用模板参数x匹配b<int>的模板专门化,即使x继承自b<int>,因为对于编译器要选择的模板专门化,类型必须完全匹配。

相反,如果要确保模板参数是从某个基类派生的类的实例,则可以考虑如下内容:

代码语言:javascript
复制
template<typename TDerived, typename TBase>
struct AssertInheritedType
{
    inline AssertInheritedType(void)
    {
        if (false)
        {
            TBase * p1 = static_cast<TDerived *>(0);    // If compiler error here, TDerived* cannot be implicitly cast into TBase*
            p1 = p1;
        }
    } // AssertInheritedType()
}; // struct AssertInheritedType

要使用此功能,您需要执行以下操作:

代码语言:javascript
复制
template<typename M>
void do_stuff(M thing)
{
    AssertInheritedType<M, b<int> >();
    a<M> whatevs;
}

如果参数不是从b<int>派生的,这将导致do_stuff()实例的编译失败。

票数 1
EN

Stack Overflow用户

发布于 2014-03-09 12:11:23

我认为这是不可能的。一个模板的两个不同的实例没有任何共同之处,它不像继承那样工作。

代码语言:javascript
复制
class x : public b<int>
{
};
class y : public b<float>
{
};

这里的类x和y没有共同的祖先,因为b和b是完全不同的类。

编辑:您可以为b类提供祖先,它不是模板。我不知道专门化这个模板的其他方法,在C++11中它看起来像这样:

代码语言:javascript
复制
#include <type_traits>

class b_base
{
};
template<typename S,typename U = void>
class a;

template<typename T>
class b: public b_base
{
};

class x : public b<int>
{
};
class z
{
};

template<typename T>
class a<T,typename std::enable_if<std::is_base_of<b_base, T>::value>::type>
{
};

int main()
{
  //this works
  a<x> c1;
  //this doesn't
  a<z> c1;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22278003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档