C++ 模板常量类型转换运算符在linux(gcc)下不工作

C++ 模板常量类型转换运算符在linux(gcc)下不工作,c++,templates,types,constants,type-conversion,C++,Templates,Types,Constants,Type Conversion,考虑以下计划: #include <iostream> template<int s> class Pack { public: Pack(){} char data[s]; template<typename X> operator X&(){ return *reinterpret_cast<X*>(data); } template<typename X> operator X const

考虑以下计划:

#include <iostream>

template<int s>
class Pack
{
public:
    Pack(){}
    char data[s];
    template<typename X> operator X&(){ return *reinterpret_cast<X*>(data); }
    template<typename X> operator X const&()const{ return *reinterpret_cast<const X*>(data); }
};

int main()
{
    const Pack<8> p;
    const double d(p);
    std::cout<<d<<std::endl;
}
#包括
模板
课程包
{
公众:
Pack(){}
字符数据;
模板运算符X&({return*reinterpret_cast(data);}
模板运算符X const&()const{return*重新解释_cast(data);}
};
int main()
{
常数包p;
常数双d(p);

std::cout根据C++03标准,该代码的格式不正确,因为模板参数推断将无法根据
常量double
推断
X&
X常量&

C++03未说明在推导之前,引用已从转换函数的返回类型中剥离,因此在您的情况下永远无法获得匹配项。对于C++0x,它包含在最新的工作报告中,因此它可能会使用某些编译器进行编译,这些编译器包含追溯性修复

您的代码实际上有一个不同的问题:GCC确实实现了缺陷报告解决方案,因此比较了
double
(它在扣除之前去掉了cv限定符!)针对
X
X const
。只有
X
匹配,因此只有第一个转换函数是带有
const Pack
参数的调用中的单个候选函数-这就是GCC抱怨转换函数缺少
const
的原因。如果您尝试以下代码,它会工作

// can't strip cv-qualifiers off "double const&" - there are no top-level 
// cv qualifiers present here!
double const &d(p);

我在GCC(和Comeau)中遇到了一个不同的错误。它找不到任何转换函数。可能是因为它正在寻找一个转换函数,例如
operator double()
,但找不到合适的函数(因为提供的函数也有一个引用)-如果这是一个好主意,为什么不使用命名成员函数?@UncleBens,你是对的,请参见下文。我不想使用运算符double(),因为Pack类应可转换为任何类型。我发布的示例被剥离以演示该问题。为什么从
double
中剥离常量限定符?如果添加
运算符double const&()const
?你可能是对的,但我还不明白…@Sven,因为
const
没有意义。无论如何,该值都是从转换函数的返回中复制的。
const
只有当它埋在指针或引用中时才有意义。当你执行
运算符double const&
时,它匹配,因为它没有hen不需要模板参数推导。这里的关键只是模板参数推导:这会产生候选函数重载,而解析在处理模板时会考虑这些重载。如果您编写
运算符双常量&
,那么您将显式提供候选函数,而这里的候选函数可以用一个更简单的例子试试:
template void f(T*);
如果你用
f(0)
调用它,它将不起作用,因为
T*
int
的模板参数推断失败。但是如果你声明一个
void f(char*);
然后调用
f(0)
它工作得非常好。感谢您的深入解释。我知道
const
没有什么意义,但我不明白编译器为什么会删除它。在这种情况下,它会有所不同,对吗?所以在这种情况下,它有意义。我想这是C++0x中固定的。关于我的第二个问题:我知道模板参数推断和函数参数类型匹配之间的区别。我只是不理解为什么在一种情况下
const
会被删除,而在另一种情况下不会。
// can't strip cv-qualifiers off "double const&" - there are no top-level 
// cv qualifiers present here!
double const &d(p);