gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:49:05 26 4
gpt4 key购买 nike

考虑代码

     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&>{};

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

     A<int*&>
A<const int*>
A<int*[3]>

但下面的不起作用:

     A<const int[3]>

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

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

编辑

我忘了提到有问题的错误是一个模棱两可的类模板实例化,它无法决定是对 const 的重载还是对数组的重载。

EDIT2

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

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

使用类型特征设施来实现一个 type_descriptor 类模板,其实例在流式传输时打印其模板参数的类型:注意:我们不能使用 RTTI 达到同样的效果,因为根据标准的 18.5.1 [lib.type.info] 第 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

示例用法是:

      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;

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

int *int * [3]Unknown *int const &int const * const &int [4]int (*)()int * & (*)(Unknown const &)int * &int []long const []

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

最佳答案

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

所以你应该修复特化。

关于传递 const 数组时 C++ 错误区分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12925677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com