簡體   English   中英

在C ++中是否可以在有和沒有編譯時常量的情況下使用相同的代碼?

[英]Is it possible in C++ to use the same code with and without compile time constants?

說你有這樣的功能:

double do_it(int m)
{
   double result = 0;

   for(int i = 0; i < m; i++)
      result += i;

   return result;
}

如果你在編譯時知道m,你可以這樣做:

template<size_t t_m>
double do_it()
{
   double result = 0;

   for(int i = 0; i < t_m; i++)
      result += i;

   return result;   
}

這樣可以在優化時循環展開。 但是,有時您可能在編譯時知道某些情況,而在運行時可能會知道某些情況。 或者,也許您有默認值,用戶可以更改...但優化默認情況會很好。

我想知道是否有任何方法可以提供兩個版本而不會基本上復制代碼或使用宏?

請注意,上面是一個玩具示例來說明這一點。

就語言規范而言,沒有通用的方法來使功能以您想要的方式工作。 但這並不意味着編譯器無法為您做到這一點。

這樣可以在優化時循環展開。

你這樣說,好像編譯器無法解開循環。

編譯器可以展開模板循環的原因是由於以下內容的匯合:

  1. 編譯器具有函數的定義。 在這種情況下,函數定義設置(這是一個模板函數,所以它的定義必須提供)。

  2. 編譯器具有循環計數器的編譯時值。 在這種情況下,通過模板參數。

但這些因素都沒有明確要求模板。 如果編譯器具有函數的定義,並且它可以確定循環計數器的編譯時值,則它具有展開該循環所需的100%信息。

如何獲取此信息無關緊要。 它可以是一個inline函數(您必須提供定義),您可以將編譯時常量作為參數調用。 它可以是一個constexpr函數(同樣,你必須提供定義),你給出一個編譯時常量作為參數。

這是實施質量的問題,而不是語言問題。 如果編譯時參數永遠是一個東西,它將支持你不能做的事情,不支持優化(或至少不支持編譯器優化)。 例如,您不能擁有一個返回std::array的函數,該std::array的長度由常規函數參數而不是模板參數指定。

是的,你可以使用std::integral_constant 具體來說,以下函數將使用int ,以及std::integral_constant

template<class Num>
constexpr double do_it(Num m_unconverted) {
  double result = 0.;
  int m_converted = static_cast<int>(m_unconverted);
  for(int i = 0; i < m_converted; i++){ result += i; }
  return result;
}

如果要使用編譯時常量調用do_it ,則可以使用

constexpr double result = do_it(std::integral_constant<int, 5>{});

否則,就是這樣

double result = do_it(some_number);

使用constexpr (至少需要C ++ 14,以允許for ):

constexpr double do_it(int m)
{
   double result = 0;

   for(int i = 0; i < m; i++)
      result += i;

   return result;
}

constexpr double it_result = do_it(10) + 1;  // compile time `do_it`, possibly runtime `+ 1`

int main() {
    int x;
    cin >> x;
    do_it(x);  // runtime
}

如果要強制constexpr值作為運行時表達式的一部分內聯,可以使用此注釋中的FORCE_CT_EVAL

#include <utility>
#define FORCE_CT_EVAL(func) [](){constexpr auto ___expr = func; return std::move(___expr);}()

double it_result = FORCE_CT_EVAL(do_it(10));  // compile time

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM