IT技术博客大学习 共学习 共进步

gcc对Template Template Parameters的兼容性

Yunjie Blog 2012-08-15 13:39:40 浏览 2,424 次

     上周有位网友联系我说chaos在他的环境上编译不过,并发给我了一些错误信息

     查看了编译错误信息之后并没得到太多排查的入口,询问了对方的编译器版本是gcc 4.6.3,而我基本都是工作在4.1版本左右的gcc上,周末在家自己搭了个4.6.3的环境,果然也出现了同样的问题,之后发现这是因为高版本gcc(g++)对c++模板的检查更为严格所导致的,我们直接看例子

struct foo_t
{
    int a;
};

template< typename T, template< typename T2 > class C >
class cc_t
{
private:
    C< T >                m_c;
};

int main()
{
    cc_t< foo_t*, std::priority_queue > cc;

    return 0;
}

     这里的cc_t类使用了模板参数嵌套模板(template template parameters)的用法,C作为一个模板容器类,T作为数据类型,然后我们在main函数中传入foo_t*数据类型和std::priority_queue,在4.1.3的g++版本中可以很和谐地编译通过,但是在4.6.3的版本中,编译器报出如下错误:

main.cpp: In function 'int main()':
main.cpp:20:39: error: type/value mismatch at argument 2 in template parameter list for 'template class C> class cc_t'
main.cpp:20:39: error:   expected a template of type 'template class C', got 'template class std::priority_queue'
main.cpp:20:43: error: invalid type in declaration before ';' token
 意思很明确,stl的priority_queue的模板参数具有三个参数,但后两个参数(_Sequence, _Compare)stl都提供了默认模板参数,我们在常规使用时可以不用指定,但这里4.6.3的g++编译器对模板参数嵌套模板的语法加强了类型检测,会导致编译不过
我的解决方案也简单
struct foo_t
{
    int a;
};

template< typename T, template< typename T2 > class C >
class cc_t
{
private:
    C< T >                m_c;
};

template
class pq_t : public priority_queue
{
};

int main()
{
    cc_t< foo_t*, pq_t > cc;

    return 0;
}
多增加一个pq_t类作为适配,这样即能编译通过
https://github.com/lyjdamzwf/chaos/blob/master/chaos/task_service/timer_container.h
和 
https://github.com/lyjdamzwf/chaos/blob/master/chaos/task_service/task_queue.h
中都出现了这样的问题,现已通过增加适配类的方式解决,如果大家有更好的方案希望指教
最后吐槽,要做具备兼容性或跨平台的东西坑还真多

建议继续学习

  1. gcc的内联汇编取全局变量地址 (阅读 4,883)
  2. GCC编译错误 (阅读 2,926)
  3. 有关最近GCC编译出现的firstdefine问题 (阅读 2,663)