标签: compile-time-constant

在 C++ 11 中,如果函数参数是编译时常量,是否有任何方法可以进行分支?

无论如何,我是否可以判断函数参数在 C++ 11 中是否是编译时间常数?我想根据结果对函数体进行分支。例如,如下所示;

template <T>
size_t get_length(const T &t)
{
    return t.size();
}

template <typename T, size_t N>
size_t get_length(const std::array<T, N> &t)
{
    return N;
}

// Maybe some template
??? foo(size_t length)
{
    ...
    // If length could be evaluated at compile time,
    return std::array<int, length>{};

    ...
    // Otherwise,
    return std::vector<int>(length);
}


// ??? and auto should be std::array if bar is std::array, std::vector if bar is std::vector or etc.
auto x = foo(get_length(bar));

Run Code Online (Sandbox Code Playgroud)

我相信这需要两项任务;首先,它应该能够确定一个值是否在编译时可评估。其次,如果可能的话,将值转换为编译时间常数。

无论如何有人可以做到这一点吗?或者有什么理由这是不可能的吗?似乎有人说使用模板函数,但这迫使调用者输入编译时间常数,而不是我想要的。

c++ templates compile-time-constant c++11

10
推荐指数
1
解决办法
1363
查看次数

C++编译时常量检测

存在库源可用的情况,并且它通常必须支持变量参数,但实际上这些参数通常是常量.

然后可以通过对常量参数的特殊处理来优化事物(例如,使用静态数组而不是堆分配),但为此必须首先确定某些事物是否是常量(或者可能定义一些宏,但它不太方便).

所以这是一个有效的实现.

更新:也在这里:http://codepad.org/ngP7Kt1V

  1. 它真的是一个有效的C++吗?
  2. 有没有办法摆脱这些宏?(is_const()不能是函数,因为函数依赖在数组大小表达式中不起作用;它也不能是模板,因为它也不接受变量参数.)

更新:这是一个更符合预期用途的更新.if(N==0)如果N不是0 ,编译器将不会为分支生成任何代码.如果需要,我们可以切换到完全不同的数据结构.当然它不完美,但这就是我发布这个问题的原因.


 #include <stdio.h>

struct chkconst { struct Temp { Temp( int x ) {} }; static char chk2( void* ) { return 0; } static int chk2( Temp ) { return 0; } }; #define is_const_0(X) (sizeof(chkconst::chk2(X))<sizeof(int)) #define is_const_0i(X) (sizeof(chkconst::chk2(X))>sizeof(char)) #define is_const(X) is_const_0( (X)^((X)&0x7FFFFFFF) ) #define const_bit(X1,bit) (is_const_0i((X1)&(1<<bit))<<bit) #define const_nibl(X1,bit) const_bit(X1,bit) | const_bit(X1,(bit+1)) | const_bit(X1,(bit+2)) | const_bit(X1,(bit+3)) #define const_byte(X1,bit) const_nibl(X1,bit) | const_nibl(X1,(bit+4)) #define const_word(X1,bit) const_byte(X1,bit) …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming compile-time-constant

9
推荐指数
1
解决办法
3964
查看次数

为什么(常量)表达式在Haskell中没有在编译时计算?

我目前正在学习Haskell,有一件事令我感到困惑:

当我构建一个复杂的表达式(其计算需要一些时间)并且该表达式是常量(意味着它只构建已知的硬编码值)时,不会在编译时计算表达式.

来自C/C++背景我习惯于这种优化.

在Haskell/GHC中执行此类优化(默认情况下)的原因是什么?有什么好处,如果有的话?

data Tree a =
   EmptyTree
 | Node a (Tree a) (Tree a)
 deriving (Show, Read, Eq)

elementToTree :: a -> Tree a
elementToTree x = Node x EmptyTree EmptyTree

treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = elementToTree x
treeInsert x (Node a left right)
  | x == a = Node x left right
  | x < a  = Node a (treeInsert x left) right
  | …
Run Code Online (Sandbox Code Playgroud)

optimization performance haskell compile-time-constant compile-time

9
推荐指数
2
解决办法
1484
查看次数

编译时的顶级表达式评估

有没有办法确保在编译时评估如下表达式?

myList :: [Int]
myList = sort [3,2,0,1]
Run Code Online (Sandbox Code Playgroud)

haskell compile-time-constant

9
推荐指数
1
解决办法
220
查看次数

为什么g ++ 5.4不能编译这个编译时的素数代码?

#include<iostream>
using namespace std;

template<int N> class Prime
{ // generate N prime numbers at compile time
public:
    unsigned int arr[N]{};
    constexpr Prime() {
        int k=0;
        for(unsigned int i=2; k<N; i++) {
            bool isPrime = true;
            for(int j=0; j<k; j++) {
                if(arr[j] > i/2) break;
                if(i % arr[j] == 0) {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime) arr[k++] = i;
        }
    }
};
int main()
{
    Prime<50000> prime; // if 50000->5000, ok
    for(auto& a : prime.arr) cout << a …
Run Code Online (Sandbox Code Playgroud)

c++ templates compiler-errors compile-time-constant constexpr

9
推荐指数
1
解决办法
206
查看次数

即使L后缀,C中的十六进制常量也是无符号的

我知道这是一个简单的问题,但我很困惑.我有一个相当典型的gcc警告,通常很容易修复:
warning: comparison between signed and unsigned integer expressions

每当我有一个带有最高有效位的十六进制常量时,如0x80000000L,编译器会将其解释为无符号.例如,使用-Wextra编译此代码将导致警告(gcc 4.4x,4.5x):

int main()
{
long test = 1;
long *p = &test;
if(*p != 0x80000000L) printf("test");
}
Run Code Online (Sandbox Code Playgroud)

我已经特别为常量加了后缀,为什么会发生这种情况呢?

c comparison gcc compile-time-constant gcc-warning

8
推荐指数
1
解决办法
4782
查看次数

如何在编译时获取通用参数类型名称?

我正在尝试实现泛型类.它应该有一个属性,该属性需要一个编译时常量,我想将其设置为参数类型的名称.像这样的东西:

namespace Example
{
    public class MyGeneric<T>
    {
        [SomeAttribute(CompileTimeConstant)]
        public int MyProperty { get; set; }

        private const string CompileTimeConstant = typeof(T).Name; // error CS0133:
        // The expression being assigned to `Example.MyGeneric<T>.CompileTimeConstant' must be constant
    }
}
Run Code Online (Sandbox Code Playgroud)

但是因为typeof(T).Name在运行时进行评估,所以它不起作用.可能吗?

c# generics reflection compile-time-constant compile-time

8
推荐指数
1
解决办法
667
查看次数

变量如何既可以是constexpr而不是constexpr?

我做了一个constexpr字符串类型,我打电话给StaticString.我从这个网站得到了这个想法.

我有一些奇怪的问题,编译器将变量视为constexpr一行,然后不是constexpr下一行.

这是代码:

constexpr StaticString hello = "hello";
constexpr StaticString hello2 = hello + " ";
constexpr StaticString world = "world";
constexpr StaticString both = hello + " world";
constexpr StaticString both2 = hello2 + world;
//This works fine (world is constexpr?)

//constexpr StaticString both3 = "hello " + world; 
//ERROR: "world" is not constexpr

int main(void)
{
    static_assert(hello[4] == 'o' ,"ERROR");
    static_assert(hello == "hello", "ERROR");
    static_assert(both2 == "hello world", …
Run Code Online (Sandbox Code Playgroud)

c++ compile-time-constant constexpr

8
推荐指数
1
解决办法
283
查看次数

编译时间文本到数字翻译 (atoi)

我想在编译时实现 atoi() 函数(在 C++ 语言中,使用 C++11 或 C++14 标准)。所以它应该能够将双引号括起来的文本解析为数字,或者报告错误。更具体地说,它是更大系统的一部分,能够在编译时解析类似 printf 的格式。而且我想在单词上拆分格式字符串,如果某些特定单词可以用数字表示 - 输出数字而不是字符串(在场景后面是序列化器类,它可以比字符串更有效地序列化数字,哪个更重要的是,反序列化器不应该尝试将每个字符串解析为数字,因为格式字符串中打印的所有数字始终表示为数字,而不是字符串)...

据我所知,有两种方法可以解决任务:

1) 通过使用 constexpr 函数;

2)通过模板元编程。

哪种方式可以更好?我尝试了第一种方式,我可以看到这种方式存在很多障碍:尤其是与 c++11 相关的限制很少。看起来第二个可能更可取,但它需要一些技巧(您需要使用运算符“”来拆分 c 字符串以分隔字符,这在从 c++14 开始的 gcc 和从 c++11 开始的 clangs 中支持)。此外,完全基于 TMP 的解决方案可能太大且太纠结。

以下是我的解决方案,我很高兴听到一些关于它的建议。

http://coliru.stacked-crooked.com/a/0b8f1fae9d9b714b


#include <stdio.h>

template <typename T> struct Result
{
    T value;
    bool valid;

    constexpr Result(T v) : value(v), valid(true) {}
    constexpr Result() : value(), valid(false) {}
};

template <typename T>
constexpr Result<T> _atoi_oct(const char *s, size_t n, T val, int sign)
{
    return n == …
Run Code Online (Sandbox Code Playgroud)

c++ compile-time-constant compile-time template-meta-programming c++11

8
推荐指数
1
解决办法
311
查看次数

$?CLASS 和 ::?CLASS 有什么区别

Raku 文档将其描述 ::?CLASS为一个编译时变量,用于回答“我属于哪个类?”。然后,在几段之后,它提到$?CLASS,并说它回答了“我在哪个班级?(作为变量)”。

\n

这两个变量有什么区别?它们通常似乎包含相同的值 \xe2\x80\x93 他们总是吗?还是有我没有观察到的差异?

\n

compile-time-constant rakudo compile-time raku

8
推荐指数
1
解决办法
123
查看次数