[英]Cast struct pointer to double pointer
我具有以下結構:
typedef struct
{
double r, i;
} doublecomplex;
我想將doublecomplex*
為double*
。 可能嗎?
我開始使用OpenBlas,它具有用於復雜值的double*
參數。 我還想知道是否有可能進行其他方式的轉換,因為某些函數返回openblas_complex_double
,即:
typedef struct { double real, imag; } openblas_complex_double;
兩種類型都是標准布局中的布局兼容類型。 因此,C ++標准保證可以將指向任何一個struct
的指針安全地reinterpret_cast
為指向其第一個數據成員的指針。
double
get_real_part(const doublecomplex *const ptr)
{
static_assert(std::is_standard_layout<doublecomplex>::value,
"cast of non-standard layout type is not safe");
const double *const realptr = reinterpret_cast<const double *>(ptr);
return *realptr;
}
但是請注意,盡管允許這樣做,但樣式仍然很差,您必須格外小心,以免表現出色。 如果有一種方法可以避免這樣做,則應該這樣做。
另外,請不要在C ++中對您的struct
進行typedef
。 完全沒有必要。
是。 對於普通的舊數據類型(POD),可以確保在適當轉換后指向POD實例的指針指向其第一個數據類型。 因此,您可以執行以下操作:
#include <iostream>
struct doublecomplex
{
double r, i;
};
int main() {
doublecomplex d{1,2};
double *dp = reinterpret_cast<double*>(&d);
std::cout << *dp << 1[dp]; // ==dp[1]==convoluted way to say dp+1
return 0;
}
OpenBlas是具有C API和C鏈接的C庫。 當然可以從C ++使用它,但不能獲得C ++庫的完整類型安全性。 C庫通常接受void*
並根據約定和/或其他功能參數對其進行解釋。 與C ++庫相比,這將使編譯器無法檢查您是否傳遞了有意義的值。
如果您的代碼完全是C ++,則可以考慮使用C ++線性代數包,或將自己的類型安全的C ++接口(純內聯)編寫到OpenBlas。
就您的情況而言,將執行簡單的C樣式強制轉換或等效的reinterpret_cast<>
。
正如@ 5gon12eder所指出的,普通(C樣式) struct
的第一個成員的地址與該struct
實例本身的地址相同。 但是,您需要注意一些陷阱。
首先,該屬性並不適用於該結構的任何其他成員,所以你不能只投的指針doublecomplex
的指針數組double
,並用它來訪問任何元素超過第一(你也許能,但語言規范並不能為您提供保證)。
其次,如果可以的話,在沒有任何強制轉換的情況下訪問成員總是比較安全的
const doublecomplex * dc;
const double * rp = & dc->r;
const double * ip = & dc->i;
優於
const doublecomplex * dc;
const double * rp = reinterpret_cast<const double *>(dc);
const double * ip = ???;
現在,如果一個函數接收double *
作為參數,你知道它的元素r
一的doublecomplex
,你可以放心地將其轉換為doublecomplex *
,但這樣做往往是自找麻煩,因為它需要有人調用該函數如下那條規則。
理想情況下,您的聲明應指定足夠詳細的類型,以免完全進行強制類型轉換,但只要您知道該語言所施加的約束(以及編譯器實現者提供的相應自由度),在存在和存在之間就存在一個清晰的界限。安全。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.