Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板转换运算符-请求从转换为非标量类型_C++_Templates_Typecast Operator - Fatal编程技术网

C++ C++;模板转换运算符-请求从转换为非标量类型

C++ C++;模板转换运算符-请求从转换为非标量类型,c++,templates,typecast-operator,C++,Templates,Typecast Operator,我试图理解cast操作符如何处理模板 考虑以下代码: #include <iostream> using namespace std; struct S { int v; }; class A { public: A(void* ptr) : ptr(ptr) {} void* ptr; template<typename T> const T& as() const { return *stat

我试图理解cast操作符如何处理模板

考虑以下代码:

#include <iostream>

using namespace std;

struct S {
    int v;
};

class A {
public:
    A(void* ptr) : ptr(ptr) {}  
    void* ptr;

    template<typename T>
    const T& as() const {
        return *static_cast<T*>(ptr);
    }

    template<typename T>
    operator const T&() const {
        return as<T>();
    }
};

int main() {
    S test;
    test.v = 123;

    A a(&test);

    S s = a.as<S>();
    S s2 = a; // error here
    const S& s3 = a;

    cout << s.v << endl;
    cout << s2.v << endl;
    cout << s3.v << endl;

    return 0;
}
#包括
使用名称空间std;
结构{
INTV;
};
甲级{
公众:
A(void*ptr):ptr(ptr){}
无效*ptr;
模板
常量T&as()常量{
返回*static_cast(ptr);
}
模板
运算符常量T&()常量{
返回为();
}
};
int main(){
S检验;
试验v=123;
A&测试;
S=a.as();
s2=a;//此处有错误
常数S&s3=a;

CUT< P>这是因为初始化代码< S2< /Cord>使用<代码> const s&< /Cuth>需要两个转换;一个将引用转换为临时,一个将临时复制到变量中。C++只允许一个自动转换发生。 例如,这也适用于:

S s2(a);
因为不再需要创建临时文件

请注意,该标准中有一个关于这种特殊情况的段落。在C++03 8.5p14中:

否则(即,对于剩余的复制初始化情况),可从源类型转换为目标类型或(当使用转换函数时)转换为其派生类的用户定义转换序列按13.3.1.4所述进行枚举,并通过重载解析(13.3)选择最佳转换序列。如果转换无法完成或不明确,则初始化的格式不正确。调用所选函数时,将使用初始化器表达式作为参数;如果函数是构造函数,则调用将初始化目标类型的临时值。调用的结果(对于构造函数而言是临时的)然后,根据上述规则,用于直接初始化作为复制初始化目标的对象。在某些情况下,允许实现通过将中间结果直接构造到要初始化的对象中来消除此直接初始化中固有的复制;请参见12.2、12.8


好的,我想我明白了。我只是认为S s2;s2=a;也可以很好地编译。阅读问题也有帮助,但也显示了编译器之间的显著差异。例如,来自该问题的代码在gcc和clang上都失败。有人知道标准在使用“通过赋值构造”时说了什么并允许什么吗特别是语法?@user1492625:这叫做复制初始化。关于这个特殊情况有一段。我会把它添加到我的答案中。