這個問題在這里已經有了答案: 函式標題中的箭頭運算子 (->) 3 個答案 8 小時前關閉。
我一直在研究 DaveJone (eevblog) uSupply 專案使用的一些嵌入式 C 韌體
https://gitlab.com/eevblog/usupply-firmware。
有一種常見的代碼模式,我無法完全理解正在發生的事情。
例如:在檔案“RegistersRCC.hpp”中有一個模板結構:
template <std::size_t A>
struct CR : public General::u32_reg<A>
{
using base_t = General::u32_reg<A>;
using base_t::base_t;
//PLL register bits
auto PLLRDY () { return base_t::template Actual<RCC_CR_PLLRDY>(); }
auto PLLON () { return base_t::template Actual<RCC_CR_PLLON>(); }
//PLL Management functions
void EnablePLL() noexcept
{
if ( not PLLON().Get() )
{
PLLON() = true;
while ( not PLLRDY().Get() );
}
}
void DisablePLL() noexcept
{
if ( PLLON().Get() )
{
PLLON() = false;
while ( PLLRDY().Get() );
}
}
//Enable clock security
auto CSSON () { return base_t::template Actual<RCC_CR_CSSON>(); }
//High speed external oscillator bits
auto HSEBYP () { return base_t::template Actual<RCC_CR_HSEBYP>(); }
auto HSERDY () { return base_t::template Actual<RCC_CR_HSERDY>(); }
auto HSEON () { return base_t::template Actual<RCC_CR_HSEON>(); }
//HSE Management functions
void EnableHSE()
{
if ( not HSEON().Get() )
{
HSEON() = true; //Enable the clock
while( not HSERDY().Get() ); //Wait for it to stable
}
}
void DisableHSE()
{
if ( HSEON().Get() )
{
HSEON() = false; //Disable the clock
while( HSERDY().Get() ); //Wait for it to disable
}
}
void ConnectHSE()
{
HSEBYP() = false; //Connect it to system
}
void BypassHSE()
{
HSEBYP() = true; //Disconnect it to system
}
//High speed internal oscillator bits
auto HSICAL () { return base_t::template Actual<RCC_CR_HSICAL>(); }
auto HSITRIM() { return base_t::template Actual<RCC_CR_HSITRIM>(); }
auto HSIRDY () { return base_t::template Actual<RCC_CR_HSIRDY>(); }
auto HSION () { return base_t::template Actual<RCC_CR_HSION>(); }
//HSI Management functions, No calibration provided
// these chips are factory calibrated
void EnableHSI()
{
if (not HSION().Get())
{
HSION() = true;
while (!HSIRDY());
}
}
void DisableHSI()
{
if ( HSION().Get() )
{
HSION() = false;
while (HSIRDY());
}
}
};
此結構存在于命名空間中:
namespace Peripherals::RCCGeneral
{
}
在同一個命名空間/頭檔案中有這個“默認”
CR() -> CR<RCC_BASE offsetof(RCC_TypeDef, CR)>;
我想這就是我理解上的差距所在。這里發生了什么?特別是左值和箭頭運算子,以及為什么它位于標題中。
在使用 RCCRegisters 的檔案中,您會看到如下用法:
CR{}.DisablePLL();
uj5u.com熱心網友回復:
這稱為類模板引數推導(CTAD),它允許為編譯器撰寫關于如何從建構式呼叫中推導模板引數的推導指南。
這是一個方便的 C 17 附加功能,可以節省輸入:
std::vector x{1.,2.,3.} //deduces std::vector<double>
std::vector<double>對于一些更復雜的示例,C 14 及更早版本需要顯式撰寫變得乏味且過于冗長的代碼。
在這種情況下,指南
CR() -> CR<RCC_BASE offsetof(RCC_TypeDef, CR)>;
指定默認建構式應將A模板引數推匯出為RCC_BASE offsetof(RCC_TypeDef, CR).
只需使用默認模板引數即可實作相同的目的:
template <std::size_t A = default_value>
struct CR : public General::u32_reg<A>{ ... };
但問題來了,offsetof(RCC_TypeDef, CR)在這里無效,因為在這條線上,CR還不存在。
所以我的假設是解決這個限制,允許默認值取決于類定義本身,我認為這很聰明。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/513844.html
標籤:C
上一篇:C 不能只回傳字串的第n個元素
