静态/动态/ const / reinterpret_cast可以在未评估的上下文中使用吗?

时间:2016-09-23 21:27:04

标签: c++ casting c++14 c++17

我尝试提供用于检查的结构B是(选择强制转换) - 可投放到#include <iostream> #include <type_traits> #include <string> template<class, class, class, class = void> struct is_valid_ternary_operator : std::false_type { }; template<class T, class S, class R> struct is_valid_ternary_operator <T, S, R, std::void_t<decltype(std::declval<T>() ? std::declval<S>() : std::declval<R>())>> : std::true_type { }; int main() { //true? 1 : 0 //is ok std::cout << is_valid_ternary_operator<bool, int, int>::value << std::endl; //true? 1 : std::string("0") //would be error std::cout << is_valid_ternary_operator<bool, int, std::string>::value << std::endl; //true? std::string("1") : std::string("0") //ok std::cout << is_valid_ternary_operator<bool, std::string, std::string>::value << std::endl; //std::string("1")? 1 : 0 //error std::cout << is_valid_ternary_operator<std::string, int, int>::value << std::endl; } 。 所有四个演员都会有完全相同的实现,期望他们的名字(本地宏观能力定义是可能的,但不是必需的)。我写了许多check-for运算符结构,例如:

template<class T, class S, class = void>
struct is_static_cast_able : std::false_type
{ };

template<class T, class S>
struct is_static_cast_able<T, S, 
                           std::void_t<decltype(static_cast<std::declval<S>()>
                                                           (std::declval<T>()))>> : std::true_type
{ };

JSONP in JQuery

显示预期输出。但现在考虑对演员表做同样的事情:

main.cpp:12:84: error: template argument 1 is invalid
    (std::declval<T>()))>> : std::true_type
                        ^~
main.cpp:12:94: error: template argument 3 is invalid
    (std::declval<T>()))>> : std::true_type
                                  ^~~~~~~~~

但它会产生错误:

=" DateValue="&TEXT(B1,"yyyy-mm-dd")&" "

Live example

不允许在未评估的情境中使用演员表吗?

2 个答案:

答案 0 :(得分:3)

  

不允许在未评估的情境中使用演员表吗?

简短回答:是的,这是允许的。

无论如何,我会尝试将这个例子减少到最小的工作范围 请注意,强制转换表达式,并且它们应该与操作数未被评估的运算符一起使用(SceneBuildersizeof,{{1} },noexcept),除非明确说明相反。

例如,decltype是一个未评估的背景:

typeid

更容易举例,它有效 使用sizeof可以显示相同的内容,其操作数也未被评估:

int main() {
    unsigned int i;
    sizeof(static_cast<int>(i));
}

依此类推,我们可以使用decltype

执行类似的操作
int main() {
    unsigned int i;
    decltype(static_cast<int>(i)) j = i;
}

使用noexcept

int main() {
    unsigned int i;
    bool b = noexcept(static_cast<int>(i));
}

答案 1 :(得分:2)

#Initialization count=0 name=0 #Input while name!='-999': count=count+1 name=input("Enter stock name OR -999 to Quit:") shares=int(input("Enter number of shares:")) pp=float(input("Enter purchase price:")) sp=float(input("Enter selling price:")) commission=float(input("Enter commission:")) #Calculations amount_paid=shares*pp commission_paid_purchase=amount_paid*commission amount_sold=shares*sp commission_paid_sale=amount_sold*commission profit_loss=(amount_sold - commission_paid_sale) -(amount_paid + commission_paid_purchase) #Output print("Stock Name:", name) print("Amount paid for the stock: $", format(amount_paid, '10,.2f')) print("Commission paid on the purchase: $", format(commission_paid_purchase, '10,.2f')) print("Amount the stock sold for: $", format(amount_sold, '10,.2f')) print("Commission paid on the sale: $", format(commission_paid_sale, '10,.2f')) print("Profit (or loss if negative): $", format(profit_loss, '10,.2f')) ===============================OUTPUT=================================================== Enter stock name OR -999 to Quit:Google Enter number of shares:10000 Enter purchase price:39.99 Enter selling price:35.99 Enter commission:0.04 Enter stock name OR -999 to Quit:Amazon Enter number of shares:10000 Enter purchase price:15.99 Enter selling price:33.99 Enter commission:0.04 Enter stock name OR -999 to Quit:-999 Enter number of shares:10000 Enter purchase price:14.99 Enter selling price:49.99 Enter commission:0.04 Stock Name: -999 Amount paid for the stock: $ 149,900.00 Commission paid on the purchase: $ 5,996.00 Amount the stock sold for: $ 499,900.00 Commission paid on the sale: $ 19,996.00 Profit (or loss if negative): $ 324,008.00 听起来像是C ++标准库中已有的东西。为mongodb docs

对于你的问题:is_static_castable<T, S>并不总是意味着编译时间。例如,在整数和浮点类型的转换中,如果在编译时它不能这样做,编译器可能会选择为转换发出代码。虽然。它很可能出现在未经评估的背景下。

C ++中未评估的操作数非常有限: 背景是:

  • static_cast
  • decltype
  • sizeof
  • typeid

引用C ++标准草案std::is_convertible

  

在某些情况下,会出现未评估的操作数(noexcept,   [expr.typeid][expr.sizeof][expr.unary.noexcept])。一个   未评估的操作数未被评估。未评估的操作数是   被认为是一个完整的表达。

注意:[dcl.type.simple]未涵盖std::is_convertible

的所有情况

因此,为了完整起见,这就是您要对static_cast执行的操作,几乎涵盖is_static_cast_able的所有情况:

static_cast

以下测试代码通过:

template<class T, class S, class = void>
struct is_static_cast_able : std::false_type
{ };

template<class T, class S>
struct is_static_cast_able<T, S,
        std::enable_if_t<
            std::is_convertible<T, S>::value ||
            std::is_base_of<std::decay_t<T>, std::decay_t<S>>::value ||
            std::is_base_of<std::decay_t<S>, std::decay_t<T>>::value ||
            std::is_base_of<std::remove_pointer_t<T>, std::remove_pointer_t<S>>::value ||
            std::is_base_of<std::remove_pointer_t<S>, std::remove_pointer_t<T>>::value ||
            (std::is_same<T, void*>::value && std::is_pointer<S>::value) ||
            (std::is_same<S, void*>::value && std::is_pointer<T>::value)
        >
    >
: std::true_type { };

[expr/8]