标签: constexpr

用户定义类型的非类型模板参数

我正在尝试定义一个模板类,它具有用户定义类型的非类型模板参数.不幸的是,迄今没有成功.真正的代码有点过于冗长,但简化示例如下所示:

#include <iostream>

template <class T>
class Maybe {
    bool is_ = false;
    T value_;

  public:
    constexpr Maybe() = default;
    constexpr Maybe(T value) : is_(true), value_(value) {}

    constexpr bool is() const { return is_; }
};

template <Maybe<int> parm>
struct Test {
    void say() const {
        std::cout << "parm is " << (parm.is() ? "set" : "not set") << ".\n";
    }
};

int main() {
    Test<Maybe<int>{}> not_set;
    Test<Maybe<int>(2)> is_set;

    not_set.say();
    is_set.say();
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译此代码(使用Clang 3.4)时,我收到以下错误消息:

test.cc:15:22: error: a non-type template parameter …
Run Code Online (Sandbox Code Playgroud)

c++ templates constexpr c++11

3
推荐指数
1
解决办法
1365
查看次数

有没有办法用MSVS2015模拟编译时双倍常量?

我知道MSVS2013(甚至是CTP)无法处理static constexpr double数据成员,正如这个问题所证实的那样.

现在,我希望MSVS2015 Preview能够让我至少使用这个简单的构造,但是,我得到了同样的错误.所以逻辑上的下一个问题是:有没有办法用MSVC2015定义编译时双精度常量?

例:

template<typename T>
struct my_constant
{
  static constexpr const T value = 42;
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

error C2864: 'my_constant<double>::value': a static data member with an in-class initializer must have non-volatile const integral type
Run Code Online (Sandbox Code Playgroud)

这是C++ 03 mumbo-jumbo.

c++ visual-c++ constexpr c++11 visual-studio-2015

3
推荐指数
1
解决办法
274
查看次数

在不创建参数对象的情况下解析constexpr函数

精简版:

如果我有这样的功能:

constexpr bool has_some_property(Foo) { return true; }
Run Code Online (Sandbox Code Playgroud)

有没有办法调用函数而不必实际实例化Foo?如果Foo不是默认可构造的话?

长卷版本:

安东尼威廉姆斯最近写了一篇文章,详细介绍了一套为任何enum class专门用于特定模板的对象启用的免费功能.它遵循类似的方案中<ios>,std::is_error_code其中一个专门用于用户定义的类型或值的模板,以允许enable_if启用某些功能.在Anthony的案例中:

template<>
struct enable_bitmask_operators<my_bitmask>{
    static constexpr bool enable=true;
};
Run Code Online (Sandbox Code Playgroud)

然后在定义运算符时:

template<typename E>
typename std::enable_if<enable_bitmask_operators<E>::enable,E>::type
operator|(E lhs,E rhs){
Run Code Online (Sandbox Code Playgroud)

此技术的问题是模板特化必须与原始模板位于同一名称空间中,因此这不起作用:

namespace mystuff {
    enum class Foo {
        ...
    };

    // Fail: wrong namespace
    template<>
    struct enable_bitmask_operators<Foo> : std::true_type {}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用一个constexpr函数,该函数可以在与类相同的命名空间中解析:

namespace mystuff {
    enum class Foo {
        ...
    };
    constexpr bool enable_bitmask_operators(Foo) { return …
Run Code Online (Sandbox Code Playgroud)

c++ templates argument-dependent-lookup constexpr c++11

3
推荐指数
1
解决办法
648
查看次数

说下面的Point类的默认构造函数是constexpr是否正确?

B. Stroustrup在他的书"TCPL"第4版的第265页上有以下例子:

struct Point{
    int x, y, z;
    constexpr Point up(int d) { return {x, y, z+d}; }
    constexpr Poind move(int dx, int dy) { return {x+dx, y+dy}; }
};
Run Code Online (Sandbox Code Playgroud)

后来他在第266页显示:

constexpr Point p1 {10, 20, 30};     // the default constructor is constexpr
Run Code Online (Sandbox Code Playgroud)

从N4140的§7.1.5/ 4开始,我发现了以下相关要点:

  • (4.4)其函数体应为= default,或其函数体的复合语句应满足constexpr函数的函数体的约束;
  • (4.5)应初始化每个非变量非静态数据成员和基类子对象(12.6.2);

关于上面的要点,我有两点意见:

  1. 说编译器生成的默认构造函数是否struct Point具有函数体是否正确= default
  2. 即使上面我的问题的答案是yes,我也在争论编译器为struct Pointis 生成默认构造函数的事实,constexpr因为这个构造函数没有初始化成员x,y并且z与上面的项目符号(4.5)相矛盾.我在这里纠正吗?

编辑我正在介绍第三个问题,我认为总结了我在这个问题上遇到的主要困难.

我无法生成constexpr其body等于的默认构造函数的示例= default …

c++ constexpr c++14

3
推荐指数
1
解决办法
226
查看次数

用编译时生成的随机ID替换魔术ID号

我的应用包含大量ID.我想最终让其他人可以查看代码,但是不要让运行时反向工程师轻松查找容易知道的ID.此外,在开发期间,在日志文件中具有常量ID以便于调试是有帮助的.但是在运行时我想通过在Release编译期间生成这些ID来使它们随机.使用<random>lib的建议代码可以在GetRandomId1()下面看到.constexpr像在switch语句中那样在代码中使用它们.但是,我constexpr在提议的功能中使用时遇到了问题,因为<random>它不constexpr兼容.还有另一种在编译时生成随机数的方法吗?或者是在编译时生成随机数,以便在运行时用作常量来考虑constexpr

#include <iostream>
#include <random>

// this is the code I would like to use to generate a random number at compile time
/*constexpr */int GetRandomId1()
{
  std::random_device rd; // non-deterministic seed
  std::mt19937 gen( rd() ); // with constexpr uncommented: 
    // error C3250: 'rd': declaration is not allowed in 'constexpr' function body
    // error C3249: illegal statement or sub-expression for 'constexpr' function
    // error C3250: 'gen': …
Run Code Online (Sandbox Code Playgroud)

random constexpr c++11

3
推荐指数
1
解决办法
698
查看次数

使用constexpr进行错误编译

我正在尝试编译以下代码:

enum class Order : char
{
    Little,
    Big
};

constexpr Order get_order() {
    uint16_t x = 1;
    return *((uint8_t *) &x) == 0 ? Order::Big : Order::Little;
}
Run Code Online (Sandbox Code Playgroud)

我用-std=c++14标志做到这一点,但我得到了这个错误:

在函数'constexpr byteorder :: Order byteorder :: get_order()'中:/home/user/dev/c++/render/include/byteorder.h:19:1:error:constexpr function'constexpr byteorder :: Order byteorder :: get_order()'不是返回语句

看起来像c ++ 11!

如果c ++ 14在constexpr函数中允许局部变量怎么办?

Debian Jessie,gcc 4.9.2

c++ constexpr c++14

3
推荐指数
1
解决办法
1357
查看次数

取字面的地址,而不是'constexpr`

严格按照C++ 14的规则,至少cppreference.com给出的规则,不是第(1)行是一个常量表达式吗?

constexpr const int* addr(const int& ir) { return &ir; }
constexpr const int* tp = addr(5); // (1)
Run Code Online (Sandbox Code Playgroud)

确实,它不是地址常量表达式,因为&ir它不是静态对象&ir的地址(在此上下文中是临时的地址,在编译时无法知道).

但它是一个核心常量表达式,因为它不违反任何后面列出的核心常量表达式规则,它没有关于获取对象地址的后续规则.

c++ memory-address constexpr c++14

3
推荐指数
1
解决办法
208
查看次数

VS15使用constexpr和字符串文字抛出错误C2975

我正在尝试实现一个在编译时执行字符串哈希的类,如果给出了文字字符串,或者运行时(基于本文).我不是像作者那样使用FNV-1a而是使用xxHash(64bits),因为编译时计算我正在使用这段代码.

这是我的实现:

class StringHash {
public:
    class ConstCharWrapper {
    public:
        inline ConstCharWrapper( const char *Str ) : Internal(Str) {}
        const char *Internal;
    };

template <size_t N>
__forceinline StringHash( const char (&Str)[N] ) :
    m_Hash( std::integral_constant<uint64_t, xxh64::hash(Str, N-1)>::value )
{
}

inline StringHash( ConstCharWrapper Str ) :
    m_Hash( xxHash_64::Calc((const uint8_t*)Str.Internal, strlen(Str.Internal)) )
{
}

inline StringHash( const char *Str, size_t Length ) :
    m_Hash( xxHash_64::Calc((const uint8_t*)Str, Length) )
{
}

__forceinline operator uint64_t() const { …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ constexpr c++11

3
推荐指数
1
解决办法
130
查看次数

如果vs constexpr里面的constexpr函数

最近,我修改了一些if constexprif我constexpr功能,发现他们仍然正常工作,并能进行评估时,编译时间.这是一个最小的案例:

template<int N>
constexpr bool is_negative()
{
    if constexpr  (N >= 0) return false;
    else  return true; 
}
int main()
{
    constexpr  bool v = is_negative<1>();
}
Run Code Online (Sandbox Code Playgroud)

live demo

在上面的例子中,N必须在编译时知道因为它是非类型模板参数,所以if constexpr在这里工作正常.然而,这是一个constexpr功能,因此,IIRC,它是可以让即使我更换一个返回值if constexprif:

template<int N>
constexpr bool is_negative()
{
    if  (N >= 0) return false;
    else  return true; 
}
int main()
{
    constexpr  bool v = is_negative<1>();
}
Run Code Online (Sandbox Code Playgroud)

live demo

cppref来看,所有的要求A constexpr function …

c++ compile-time constexpr if-constexpr

3
推荐指数
1
解决办法
306
查看次数

为什么vc ++ 2019不接受代码?

template<int N>
void f()
{
    constexpr int n = 9;
    ++*const_cast<int*>(&n); // ok
    ++*const_cast<int*>(&N); // error C2101: '&' on constant
}

int main()
{
    f<8>();
}
Run Code Online (Sandbox Code Playgroud)

根据cppref

变量,函数,模板参数对象(自C ++ 20起)或数据成员的名称,无论类型如何,例如std :: cin或std :: endl。即使变量的类型是右值引用,由其名称组成的表达式也是左值表达式。

两个问题:

1.为什么vc ++ 2019(带有/ std:c ++ latest)不接受代码?

2.为什么C ++ 20允许模板参数对象为左值?

c++ const language-lawyer constexpr c++20

3
推荐指数
1
解决办法
160
查看次数