模板类中的模板函数is_same

5
为什么这段代码会输出 false?
//this-type.cpp  

#include <iostream>
#include <type_traits>

using namespace std;

template<typename testype>
class A
{
public:
    A()
    {
        cout << boolalpha;
        cout << is_same<decltype(*this), A<int>>::value << endl;
    }
};

class B : public A<int>
{
};

int main()
{
    B b;
}

输出:

$ g++ -std=c++11 this-type.cpp
$ ./a.out
false

A到B之间的“*this”的类型是A<int>,对吗?
3个回答

8

*this 是类型为 A 的左值,因此 decltype(*this) 将给出引用类型 A &。请注意,对左值使用 decltype 会返回引用类型:

    cout << is_same<decltype(*this), A<int>>::value << endl;
    cout << is_same<decltype(*this), A<int> &>::value << endl;

输出:

false
true

那么,“this”的完整类型是什么,“A<int>&* this”? - ABu
绝对不明显。 - Matthieu M.
最后一行对我不起作用。我的输出是'false','true','false'(g++(Ubuntu/Linaro 4.7.2-2ubuntu1)4.7.2)。 - ABu
@Peregring-lk this 是一个类型为 A<int> * 的 prvalue 表达式。对 this 进行间接引用会得到一个类型为 A<int> 的 lvalue 表达式。表达式的类型并不总是与 decltype 报告的相同。 - ecatmur
@Peregring-lk 噢,我的括号写错了。已经更正了。 - ecatmur

2

尝试:

typedef std::remove_reference<decltype(*this)>::type this_type;
cout << is_same<this_type, A<int>>::value << endl;

在某些其他情况下(如果您不关心const/volatile),也许可以使用remove_cv,例如:

typedef std::remove_reference<decltype(*this)>::type this_type;
typedef std::remove_cv<this_type>::type no_cv_this_type;
cout << is_same<no_cv_this_type, A<int>>::value << endl;

2
请确保在 remove_reference 之后使用 remove_cv。 - R. Martinho Fernandes
@R.MartinhoFernandes remove_reference 有副作用吗?为什么需要在 remove_reference 后使用 remove_cv? - ABu
@Peregring-lk 因为顺序很重要。请参见此处 http://flamingdangerzone.com/cxx11/2012/05/29/type-traits-galore.html#bare_types - R. Martinho Fernandes
@Peregring-lk,这是因为 int&const 不存在,但它与 int const& 是不同的。remove_cv 函数从类型的“最外层”中移除 const-volatile,所以会将 int*const 转换为 int*,但会保留 int const&int const* 不变。 - Yakk - Adam Nevraumont
是的,上面有一个错别字,抱歉! - Yakk - Adam Nevraumont

0

你确定 decltype(*this) 是 A 吗?你应该用一个丑陋的 cout 调试输出来调查一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接