【问题标题】:Why can't I downcast pointer to members in template arguments?为什么我不能向下转换指向模板参数中成员的指针?
【发布时间】:2010-10-26 19:14:51
【问题描述】:

如果我创建一个指向基成员的指针,我通常可以将其转换为指向派生成员的指针,但在像下面的 Buzz 这样的模板中使用时则不能,因为第一个模板参数会影响第二个模板参数.我是在与编译器错误作斗争,还是标准真的要求这不起作用?

struct Foo
{
    int x;
};

struct Bar : public Foo
{
};

template<class T, int T::* z>
struct Buzz
{
};

static int Bar::* const workaround = &Foo::x;

int main()
{
    // This works. Downcasting of pointer to members in general is fine.
    int Bar::* y = &Foo::x;

    // But this doesn't, at least in G++ 4.2 or Sun C++ 5.9. Why not?
    // Error: could not convert template argument '&Foo::x' to 'int Bar::*'
    Buzz<Bar, &Foo::x> test;

    // Sun C++ 5.9 accepts this but G++ doesn't because '&' can't appear in
    // a constant expression
    Buzz<Bar, static_cast<int Bar::*>(&Foo::x)> test;

    // Sun C++ 5.9 accepts this as well, but G++ complains "workaround cannot
    // appear in a constant expression"
    Buzz<Bar, workaround> test;

    return 0;
}

【问题讨论】:

    标签: c++ templates implicit-conversion pointer-to-member downcast


    【解决方案1】:

    这是不允许的。根据§14.3.2/5:

    对用作非类型模板参数的每个表达式执行以下转换。如果非类型模板参数无法转换为相应模板参数的类型,则该程序格式错误。
    — 对于整数或枚举类型的非类型模板参数,应用整数提升 (4.5) 和整数转换 (4.7)。
    — 对于指向对象的类型指针的非类型模板参数,应用限定转换 (4.4) 和数组到指针转换 (4.2)。 — 对于对象类型引用的非类型模板参数,不适用任何转换。引用所指的类型可能比模板参数的(否则相同的)类型更具 cv 限定。模板参数直接绑定到模板参数,模板参数必须是左值。
    — 对于指向函数的类型指针的非类型模板参数,仅应用函数到指针的转换(4.3)。如果模板参数表示一组重载函数(或指向此类函数的指针),则从集合中选择匹配函数 (13.4)。
    — 对于函数类型引用的非类型模板参数,不适用任何转换。如果模板参数表示一组重载函数,则从集合中选择匹配函数 (13.4)。
    — 对于指向成员函数的类型指针的非类型模板参数,不适用任何转换。如果模板参数表示一组重载的成员函数,则从集合中选择匹配的成员函数 (13.4)。
    对于指向数据成员的类型指针的非类型模板参数,应用限定转换 (4.4)。

    我已经强调了关于指向数据成员的指针的转换。请注意,您的转换(第 4.11/2 节)未列出。在 C++0x 中,这方面保持不变。

    【讨论】:

    • 绝对正确,但知道为什么不允许这样做吗?看起来很随意。
    • @Joseph:我也认为是这样,这就是为什么我还检查了 C++0x。 (他们删除了许多看似随意的决定,比如函数模板没有默认模板参数。)要么没有人找到它的用途,所以它并没有真正改变/所以它根本没有被推动(添加一个井更容易-测试功能而不是弃用损坏的功能),或者有一些我看不到的根本原因。
    猜你喜欢
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多