传递const数组时区分特殊化的C++错误

Sir*_*Guy 5 c++ template-specialization

考虑代码

     template <class A>
     class B;

     template <class A>
     class B<const A>{};

     template <class A, int N>
     class B<A[N]>{};

     template <class A>
     class B<A*>{};

     template <class A>
     class B<A&>{};
Run Code Online (Sandbox Code Playgroud)

以下模板实例化工作正常:

     A<int*&>
     A<const int*>
     A<int*[3]>
Run Code Online (Sandbox Code Playgroud)

但以下一个不起作用:

     A<const int[3]>
Run Code Online (Sandbox Code Playgroud)

是否有某些原因导致此特定组合无效或者它可能是g ++ 4.6.3的错误?

顺便说一句,我设法使用SFINAE和boost :: disable_if <>来解决这个问题,所以至少问题已经解决了.

编辑

我忘了提到有问题的错误是一个模糊的类模板实例化,它无法决定const的重载或数组的重载.

EDIT2

这与指针无关,这里是完整的上下文:

我正在阅读C++ Template Metaprogramming一书,我正在做问题2-3(第2章问题3),其中说:

使用类型特征工具来实现一个type_descriptor类模板,其实例在流式传输时打印其模板参数的类型:注意:根据18.5.1 [lib.type.info],我们不能使用RTTI达到相同的效果标准的第7段,typeid(T).name()不保证返回有意义的结果.

我的解决方案(包括编译错误的解决方法)如下:

    //QUESTION 2-3
    template <class T, class enable = void>
    struct type_descriptor
    {
      std::string operator()() const
      {
        return "Unknown";
      }
    };

    //specializations for primitive types
    #define TYPE_DESC_SPEC(type) template <>    \
      struct type_descriptor<type,void>     \
      {std::string operator()() const{return #type;}};

    TYPE_DESC_SPEC(int)
    TYPE_DESC_SPEC(long)
    TYPE_DESC_SPEC(void)
    TYPE_DESC_SPEC(short)
    TYPE_DESC_SPEC(unsigned char)
    TYPE_DESC_SPEC(unsigned short)
    TYPE_DESC_SPEC(unsigned long)

    //specializations for modifiers *, const, &, and [N]

    template <class T>
    struct type_descriptor<T&,void>
    {std::string operator()(){return type_descriptor<T>()() + " &";}};

    template <class T>
    struct type_descriptor<T*,void>
    {std::string operator()(){return type_descriptor<T>()() + " *";}};

    //Replace void with what's in the comment for the workaround.
    template <class T>
    struct type_descriptor<const T, void/*typename boost::disable_if<boost::is_array<T> >::type*/>
    {std::string operator()(){return type_descriptor<T>()() + " const";}};

    template <class T>
    struct type_descriptor<T(*)(),void>
    {std::string operator()(){return type_descriptor<T>()() + " (*)()";}};

    template <class T, class U>
    struct type_descriptor<T(*)(U),void>
    {std::string operator()(){return type_descriptor<T>()() + " (*)(" + type_descriptor<U>()() + ")";}};

    template <class T, int N>
    struct type_descriptor<T[N],void>
    {
      std::string operator()()
      {
        std::stringstream s;
        s << type_descriptor<T>()() << " [" << N << "]";
        return s.str();
      }
    };

    template <class T>
    struct type_descriptor<T[],void>
    {std::string operator()(){return type_descriptor<T>()() + " []";}};

    //Now overload operator<< to allow streaming of this class directly

    template <class T>
    std::ostream & operator<<(std::ostream & s, type_descriptor<T> t)
    {
      return s << t();
    }
    //END QUESTION 2-3
Run Code Online (Sandbox Code Playgroud)

示例用法是:

      std::cout << "\nQuestion 2-3 results\n";
      std::cout << type_descriptor<int*>() << std::endl;
      std::cout << type_descriptor<int*[3]>() << std::endl;
      std::cout << type_descriptor<std::string*>() << std::endl;
      std::cout << type_descriptor<const int&>() << std::endl;
      std::cout << type_descriptor<const int *const&>() << std::endl;
      std::cout << type_descriptor<int[4]>() << std::endl;
      std::cout << type_descriptor<int(*)()>() << std::endl;
      std::cout << type_descriptor<int*&(*)(const char &)>() << std::endl;
      std::cout << type_descriptor<int*&>() << std::endl;
      std::cout << type_descriptor<int[]>() << std::endl;
      std::cout << type_descriptor<const long[]>() << std::endl;
Run Code Online (Sandbox Code Playgroud)

并且相应的输出是(当解决方法进入时,否则它不会在最后一个上编译):

int *

int * [3]

Unknown *

int const &

int const * const &

int [4]

int (*)()

int * & (*)(Unknown const &)

int * &

int []

long const []

因此,C++能够区分模板参数的指针和数组,能够正确地,递归地,分离复合类型并输出正确的结果,除了const A[].它需要帮助

Joh*_*itb 1

具有 const 元素类型的数组类型既是 const 限定类型(const 双向应用)又是数组类型。

所以你应该修复专业。