C样式转换参考

时间:2020-06-26 09:25:10

标签: c++ language-lawyer

请考虑以下内容:

select c.*
from (
    select c.*, sum(usd_price) over((partition by subscription_id order by transaction_date) sum_usd_price
    from collections c
) c
where sum_usd_price >= 100 and sum_usd_price - usd_price < 100

或更简单地说,如果您对特定示例不感兴趣:

template<class T>
struct call_fn;

template< >
struct call_fn< void( ) >
{
    using sig = void ( );
    void * fn;
    void call() &&
    {
        static_cast< sig * >( fn )( );
    }
    auto && change()
    {
        return (call_fn<void __vectorcall( )>&&)(*this);
    }
};

template< >
struct call_fn< void __vectorcall( ) >
{
    using sig = void __vectorcall( );
    void * fn;
    void call() &&
    {
        static_cast< sig * >( fn )( );
    }
    auto && change()
    {
        return (call_fn<void ( )>&&)(*this);
    }
};

void __vectorcall fast()
{}
void  stdd()
{}

void foo()
{
    void * f = fast;
    void * st = stdd;
    call_fn<decltype(stdd)> { f }.change().call();
    call_fn<decltype(fast)> { st }.change().call();
}

在这种情况下,除了元编程以外,对象是相同的,这是否是定义良好的强制转换,可以进行c样式? (因为使用c ++强制转换无法通过其他任何方式完成)

1 个答案:

答案 0 :(得分:3)

(因为使用c ++强制转换无法通过其他任何方式完成)

(s<int>&&)(s<float>());

可以使用C ++样式转换完成此转换。等效为:

reinterpret_cast<s<int>&&>(s<float>());

这是定义明确的演员表

重新解释对另一个的强制转换引用已经很好定义。

在这种情况下,无法很好地定义通过重新解释的引用进行的访问。 s<int>是与s<float>不同的类型,并且该地址没有s<int>对象。


请注意,这是例外情况下允许联合类型联动的情况(标准布局结构的常见初始序列):

union U {
    s<float> sf;
    s<int>   si;
};

U u;
u.sf = {};
return u.si.f; // well defined

标准裁判:

[class.mem]

两种标准布局结构([class.prop])类型的公共初始序列是按声明顺序的最长的非静态数据成员和位域序列,从每个结构中的第一个这样的实体开始,以使相应的实体具有与布局兼容的类型,或者两个实体都使用no_unique_address属性([dcl.attr.nouniqueaddr])声明,或者都不是,并且两个实体都是具有相同宽度的位域,或者两者都不是位场。

在具有结构类型T1的活动成员的标准布局联合中,允许读取结构类型T2的另一个联合成员的非静态数据成员m,条件是m是T1的公共初始序列的一部分,并且T2;行为就像提名了T1的相应成员一样。


请注意,也可以重新解释第一个成员的地址:

s<float> sf{};
return *reinterpret_cast<char*>(&sf); // well defined

标准裁判:

[expr.reinterpret.cast]

对象指针可以显式转换为其他类型的对象指针。 将对象指针类型的prvalue v转换为对象指针类型“ cv T的指针”时,结果为static_­cast<cv T*>(static_­cast<cv void*>(v))

[expr.static.cast]

“指针指向cv1无效”类型的prvalue可以转换为“指针指向cv2 T的类型”的prvalue,其中T是对象类型,并且cv2是与cv-qualification相同或大于cv-qualification的对象。 ,cv1。 ...如果原始指针值指向对象a,并且存在类型T(忽略cv限定)的对象b,该对象可与a进行指针互换,则结果是指向b的指针

[basic.compound]

如果满足以下条件,则两个对象a和b是指针可互换的:

  • ...

  • 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,...

  • ...

相关问题