什么是implicit_cast?什么时候我应该更喜欢implicit_cast而不是static_cast?
我有一种复杂的感觉static_cast,因为它是最安全的C++演员,但同时允许安全和不安全的转换,所以你必须知道上下文,说它是否真的安全或可能导致UB(例如,当铸造时到一个子类).
那么为什么没有更安全的明确演员呢?这是一个例子,它可能是有用的.在COM中,他们必须返回接口指针void** ppv,因此"必须"明确地进行转换
*ppv = (IInterface*) this;
Run Code Online (Sandbox Code Playgroud)
然后建议用更安全的C++演员代替
*ppv = static_cast<IInterface*>(this);
Run Code Online (Sandbox Code Playgroud)
但即使在static_cast这里也有意义吗?this是一个源自的类IInterface,所以人们可以简单地写
IInterface* p = this; // implicit conversion to base, safe for sure
*ppv = p;
Run Code Online (Sandbox Code Playgroud)
或使用像帮手一样的帮手
template<class T, class U>
T implicit_cast(U p) { return p; }
*ppv = implicit_cast<IInterface*>(this);
Run Code Online (Sandbox Code Playgroud)
那么,是否真的static_cast有时会被滥用,并且implicit_cast在某些情况下可以(应该?)替换它,或者我错过了什么?
编辑:我知道在COM中需要一个强制转换,但它不一定是static_cast,隐式强制转换就足够了.
根据Scott Meyers的说法,为了防止在const版本的getter和非const版本的getter中重复代码,请从非const版本调用该方法的const版本:static_cast<const A&>(*this).Methodology(); 但是,由于过度热心而意外使用我输入的Visual Assist X Intellisense:const_cast<const A&>(*this).Methodology();它运行得很好.
在这种情况下使用特定演员阵容有什么区别?
正在使用的IDE:Visual Studio 2010.
我的问题是由stackoverflow上的这个答案激发的,/sf/answers/3365740731/.报价,
问:你如何转换
std::string_view为const char*?答:只需做一个
std::string(string_view_object).c_str()获得保证的以空值终止的临时副本(并在行尾清理它).
不幸的是,它构建了一个新的string.我想知道是否可以做到,
static_cast<string>(string_view_object).c_str()
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是:
这会构造一个新字符串吗?
是否保证返回以null结尾的char序列?
我有一小段代码用于演示.它似乎工作正常.(参见wandbox 结果)
#include <string>
#include <iostream>
#include <string_view>
#include <cstring>
int main()
{
std::string str{"0123456789"};
std::string_view sv(str.c_str(), 5);
std::cout << sv << std::endl;
std::cout << static_cast<std::string>(sv) << std::endl;
std::cout << strlen(static_cast<std::string>(sv).c_str()) << std::endl;
}
Run Code Online (Sandbox Code Playgroud) C ++ 17 noexcept是函数类型的一部分。它还允许从noexcept函数指针到潜在地抛出函数指针的隐式转换。
void (*ptr_to_noexcept)() noexcept = nullptr;
void (*ptr_to_throwing)() = ptr_to_noexcept; // implicit conversion
Run Code Online (Sandbox Code Playgroud)
http://eel.is/c++draft/expr.static.cast#7说static_cast可以执行这种转换的逆过程。
void (*noexcept_again)() noexcept = static_cast<void(*)() noexcept>(ptr_to_throwing);
Run Code Online (Sandbox Code Playgroud)
不幸的是,GCC和clang都告诉我否则:https : //godbolt.org/z/TgrL7q
正确的方法是什么?是reinterpret_cast和C风格的投我唯一的选择吗?
我发现自己处于一种我知道什么类型的东西的情况.Type是三个(或更多)继承级别之一.我调用返回的工厂B*但是T是一个类型的最高级别(如果我的代码知道它是什么)或第二级别.
无论如何,我static_cast在模板中做了一个错误的事情.我的问题是我什么时候可以安全地静态施放?有没有这样的时间?我在这种情况下做到了,因为当我意外地将T作为古怪的东西(已经发生并且)动态转换忽略(并返回null)时,我宁愿得到编译错误.但是,当我知道正确的类型时,指针未被调整,导致我有一个错误的指针.我不确定为什么在这种情况下允许静态转换.
我什么时候可以安全地使用static_cast进行向下铸造?有没有情况?现在似乎总是错误地使用a static_cast(当目的是向下投射时)
好的,我想出了如何重现它.
#include <iostream>
struct B { virtual void f1(){} };
struct D1 : B {int a;};
struct D2 : B {int a, b; };
struct DD : D1, D2 {};
int main(){
void* cptr = new DD(); //i pass it through a C interface :(
B* a = (B*)cptr;
D2* b = static_cast<D2*>(a); //incorrect ptr
D2* c = dynamic_cast<D2*>(a); //correct ptr
std::cout << a << " " <<b << " " …Run Code Online (Sandbox Code Playgroud) 我有一个const指针指向一个指针Fred,我不明白为什么一个static_cast是不够的.
typedef struct {
int n;
} Fred;
Fred *pFred;
Fred **const ppFred = &pFred;
void **const ppVoid = static_cast<void ** const>(ppFred);
Run Code Online (Sandbox Code Playgroud)
请有人能解释为什么reinterpret_cast需要一个指针转换Fred*为指针void*,但是static_cast是精指针转换Fred为指针void.
有人可以在http://en.cppreference.com/w/cpp/types/aligned_storage中解释关于铸造的一些代码吗?
可以使用以下代码
return *static_cast<const T*>(static_cast<const void*>(&data[pos]));
Run Code Online (Sandbox Code Playgroud)
被替换为
return *reinterpret_cast<const T*>(&data[pos]);
Run Code Online (Sandbox Code Playgroud)
?
为什么这里使用两个铸件?非常感谢.
香港
我的团队正在开发一个嵌入式系统,我们需要遵循MISRA C++.
我们正在重构代码以使用更少的虚方法,因此我们尝试实现CRTP以使用静态多态而不是动态多态.
但是我们遇到静态多态性需要指针转换的问题,因此我们的静态分析检查器会抱怨.
这是界面
template <typename T>
class UpdateMethod
{
protected:
~UpdateMethod() {}
public:
void operator()() const
{
// [MISRA Rule 5-2-7] violation:
static_cast<const T*>(this)->update();
}
};
Run Code Online (Sandbox Code Playgroud)
以下是其中一个实现:
class A
: public UpdateMethod<A>
{
public:
void update() const {}
};
Run Code Online (Sandbox Code Playgroud)
在通过MISRA检查程序时,它会抱怨static_cast(从ptr转换为ptr(e926).
所以,我的问题是:有没有什么好的方法来实现CRTP而不必压制MISRA警告,所以以安全的方式?
仅有关于指针转换的相关问题: MISRA C++ 2008规则5-2-7违规:指针类型的对象不应直接或间接转换为无关指针类型 我在CRTP中具有相同的错误.
编辑:正如前面提到的只有C++ 03而没有像boost这样的外部库.
取自 GCC 实现type_traits为什么static_cast需要这里?
template <typename _Tp, typename... _Args>
struct __is_nt_constructible_impl
: public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> {};
template <typename _Tp, typename _Arg>
struct __is_nt_constructible_impl<_Tp, _Arg>
: public integral_constant<bool,
// Why is `static_cast` needed here?
noexcept(static_cast<_Tp>(declval<_Arg>()))> {};
Run Code Online (Sandbox Code Playgroud) c++ ×10
static-cast ×10
alignment ×1
boost ×1
c++03 ×1
c++17 ×1
casting ×1
const-cast ×1
crtp ×1
dynamic-cast ×1
libstdc++ ×1
misra ×1
noexcept ×1
string-view ×1
type-safety ×1
type-traits ×1