代码之家  ›  专栏  ›  技术社区  ›  hsivonen

当作为函数模板的T*参数传递时,使用运算符T*强制模板类

  •  0
  • hsivonen  · 技术社区  · 17 年前

    假设我有这样一个函数模板:

    template<class T>
    inline
    void
    doStuff(T* arr)
    {
      // stuff that needs to use sizeof(T)
    }
    

    然后在另一个 .h 我有一个模板类 Foo 这包括:

    public: operator T*() const;
    

    现在,我意识到这些是不同的T。但是如果我有一个变量 Foo<Bar> f 任何 要调用的指针类型 operator T*() . 然而,如果你打电话 doStuff(f) doStuff 受不了 Foo<Bar> 而不是自动使用运算符 T*() Bar* 然后用 Bar T

    5 回复  |  直到 17 年前
        1
  •  3
  •   Leon Timmermans    17 年前

    GCC是正确的。在模板参数中,只考虑完全匹配,而不考虑类型转换。这是因为,否则可能需要考虑无限(或至少指数)的转换量。

    如果是Foo<T>是您要运行的唯一其他模板,最好的解决方案是添加:

    template<typename T> inline void doStuff(const Foo<T>& arr) {
        doStuff(static_cast<T*>(arr));
    }
    

    如果您在使用大量模板时遇到此问题,则应通过以下方法解决此问题:

    #include <boost/type_traits/is_convertible.hpp>
    #include <boost/utility/enable_if.hpp>
    template<template <typename> class T, typename U> inline typename boost::enable_if<typename boost::is_convertible<T<U>, U*>::type>::type doStuff(const T<U>& arr) {
        doStuff(static_cast<U*>(arr));
    }
    

    不过有点冗长;-)

        2
  •  2
  •   Tim B Tim B    17 年前

    这可能值得一试:

    doStuff<Bar>(f);
    

    我认为这将导致编译器期望T*为Bar*,然后使用Foo的运算符T*()执行强制转换,但我不能说我已经尝试过了。

        3
  •  0
  •   Salman A    17 年前

    利昂的想法可能是最好的。但在紧急情况下,您也可以显式调用cast操作符:

    doStuff(static_cast<Bar*>(f));
    
        4
  •  -1
  •   JaredPar    17 年前

    我不知道为什么转换不起作用,但是你可以使用重载来解决这个问题

    
    template 
    inline
    void 
    doStuff(T& arrRef)
    {
      doStuff(&arrRef);
    }
    
        5
  •  -1
  •   Paul de Vrieze    17 年前

    在你认为的意义上,T*不是和T分开的类型。指针是一个类型限定符。我不确定标准是怎么说的,但我想说的是,由于变量已经是T类型,它不会再次尝试转换。如果您想做一些自定义操作来获取指针,请重载&操作人员