c++ - 如果已知,则使用编译时常量

标签 c++ templates compile-time

我有一个神秘类型的值 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's trick ,我们可以做到以下几点:

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)>;

Here's a demo .

关于c++ - 如果已知,则使用编译时常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40077916/

相关文章:

javascript - AngularJS - 我的部分 Controller

c++ - 将整数模板参数值映射到基本类型

d - 编译时评估

c++ - C++中的编译错误(初级)

c++ - boost::hash 不适用于 c 字符串?

c++ - Eclipse 提示 : "Invalid overload of ' endl'"- but code does compile

c - 如何在编译时确定数组的长度?

gcc/clang 可以优化初始化计算吗?

c++ - C++命令行软件

c++ - 在 Windows 平台上测量 native C++ 的亚秒级运行时间