簡體   English   中英

如果已知,則使用編譯時常量

[英]Use compile-time constant if known

我有一個神秘類型T的值(對於這個例子,我們可以假設T是一個整數類型)。 我想將此值用作某些模板函數中的模板參數(對於此示例, std::integral_constant的參數)。 問題是T可能不是常量類型。 如果它不是常量類型,我想在我的模板函數中默認為0 但是,如果它是常量,我想使用該值本身,因為它是已知的。

目前,我有以下(非編譯)代碼。

#include <type_traits>

template <typename T>
struct CompileTimeStuff {
    constexpr static int value(T arg) { return 0; }
};

template <typename T>
struct CompileTimeStuff<const T> {
    constexpr static int value(const T arg) { return (int)arg; }
};

template <typename T>
constexpr int magic_function(T arg) {
    return CompileTimeStuff<T>::value(arg);
}

const int cvalue = 7;
int ivalue = 7;

// This should be 7, since cvalue is constant and thus known at compile-time.
typedef std::integral_constant<int, magic_function(cvalue)> type1;
// Since ivalue is non-constant, this should take the default value of 0.
typedef std::integral_constant<int, magic_function(ivalue)> type2;

不幸的是, g++給出了以下錯誤。

templatestuff.cpp:28:58: error: the value of ‘ivalue’ is not usable in a constant expression
 typedef std::integral_constant<int, magic_function(ivalue)> type2;

編譯器不喜歡將ivalue用作模板參數,即使我從未在實例化中直接使用它的值。

是的,你可以這樣做。 使用Johannes Schaub 的技巧,我們可以執行以下操作:

template<typename T> 
constexpr typename std::remove_reference<T>::type makeprval(T && t) {
  return t;
}

#define constexpr_or_zero(e) (noexcept(makeprval(e)) ? (e) : 0)

const int cvalue = 7;
int ivalue = 7;

using type1 = std::integral_constant<int, constexpr_or_zero(cvalue)>;
using type2 = std::integral_constant<int, constexpr_or_zero(ivalue)>;

這是一個演示

暫無
暫無

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

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