标签: constexpr

GCC 4.7.1带有重载的广义常量表达式问题

我尝试使用模板特化实现编译时算法选择.

我哈希以下代码:

template <class C>
    struct choose
    { 
        typedef size_t (*type)(const C*);
        static constexpr type value = java_string_hashcode<C>;
    };
Run Code Online (Sandbox Code Playgroud)

我将这种结构专门用于char类型:

template <>
    struct choose<char>
    { 
        typedef size_t (*type)(const char*);
        static constexpr type value = fnv_1a_32_hash;
    };
Run Code Online (Sandbox Code Playgroud)

但是当我尝试编译它时,我得到GCC 4.7.1的以下错误:

错误:字段初始值设定项不是常量

我认为问题来自于fnv_1a_32_hash函数重载的事实,即使IMO隐式转换size_t (*)(const char*)应该处理这个问题.

我终于找到了一个解决方法,通过重命名重载或简单地转换赋值:

static constexpr type value = (type)fnv_1a_32_hash;
Run Code Online (Sandbox Code Playgroud)

我的问题是:这是一个编译器错误吗?或者我错过了什么?请在需要时解释并引用规格.


fnv_1a_32_hash实施细节:

constexpr size_t fnv_1a_32_hash(const char* p, size_t h) noexcept
{ 
    return (*p == 0) ? h : fnv_1a_32_hash(p + 1, (h ^ *p) …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates constexpr c++11

5
推荐指数
1
解决办法
470
查看次数

clang中的constexpr错误但不是gcc中的错误?

我们来看一个这个简单的例子:

#include <iostream>

namespace foo {
    constexpr int main(int argc, char* argv[]) {
      // code
    }
}

int main(int argc, char* argv[])
{
    return foo::main(argc, argv);
}
Run Code Online (Sandbox Code Playgroud)

取决于代码是什么,clang会抱怨或不抱怨.如果代码是:

cout << "Hello!";
return 0;
Run Code Online (Sandbox Code Playgroud)

clang抱怨:

错误:constexpr函数永远不会产生常量表达式[-Winvalid-constexpr]

constexpr int main(int argc, char* argv[]) {
Run Code Online (Sandbox Code Playgroud)

注意:非constexpr函数'operator <<>'不能用于常量表达式

    std::cout << "Hello!";
Run Code Online (Sandbox Code Playgroud)

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:530:5:注意:在这里声明

operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
Run Code Online (Sandbox Code Playgroud)

很公平,constexpr函数不能包含任何cout语句,我们知道.但是如果我们这样做会发生什么?

  for (int i = 0; i < argc; i++)
    std::cout << argv[i];
Run Code Online (Sandbox Code Playgroud)

clang允许它!好吧,但这不可能是一个constexpr函数,即使它被标记为constexpr,让我们尝试在constexpr上下文中使用它.

int arr[foo::main(argc, argv)];
Run Code Online (Sandbox Code Playgroud)

有用!那一定是cla​​ng bug?我之所以说clang是因为gcc抱怨:

错误:constexpr函数的主体'constexpr int foo :: main(int,char**)'不是return语句 …

c++ clang constexpr c++14

5
推荐指数
2
解决办法
4441
查看次数

Lambda表达式作为常量表达式的未评估子表达式

请原谅我的长篇文章,但我不能让这个程序工作,除非我指定-fpermissivegcc而不是在clang下.你能帮我解决这个例子吗?

namespace detail
{

template<typename T>
constexpr auto address(T&& t) ->
  typename ::std::remove_reference<T>::type*
{
  return &t;
}

template <typename FP, FP fp, class C, typename ...A>
struct S
{
  static constexpr auto* l = false ? address(
    [](C* const object) noexcept
    {
      return [object](A&& ...args) {
        return (object->*fp)(::std::forward<A>(args)...); 
      };
    }) :
    nullptr
  ;
};

template <typename FP, FP fp, typename R, class C, typename ...A>
auto make_member_delegate(C* const object, R (C::* const)(A...)) ->
  decltype((*S<FP, fp, C, A...>::l)(object))
{ …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

5
推荐指数
1
解决办法
544
查看次数

在constexpr中使用简单的复制/移动分配联合时发生冲突

考虑以下代码

struct S
{
    constexpr S() = default;
    constexpr S(S const &) = default;
    constexpr S(S &) = default;
    constexpr S(S &&) = default;
#if 1
    S & operator = (S const &) = default;
    S & operator = (S &) = default;
    S & operator = (S &&) = default;
#else
    constexpr S & operator = (S const &) = default;
    constexpr S & operator = (S &) = default;
    constexpr S & operator = (S &&) = default; …
Run Code Online (Sandbox Code Playgroud)

c++ clang constexpr c++11 c++14

5
推荐指数
0
解决办法
232
查看次数

std :: experimental :: optional <T>实现:Constexpr构造函数混淆

实现 std::experimental::optional(cppreference.com)时,我对特定构造函数的规范感到困惑,即:

constexpr optional( const T& value ); // (4)
Run Code Online (Sandbox Code Playgroud)

(来源)

optional<T>对于易于破坏的类型T,该构造函数允许在constexpr上下文中构造.虽然第一个要求,即在这种情况下关闭用户提供的析构函数来制作optional<T>文字类型,直接解决,我不知道如何绕过constexpr中不允许放置限制.

我认为我应该实现optional<T>使用std::aligned_storage<T>以允许T不是默认构造的类型并满足任何对齐要求(如果适用).但正如我所说,constexpr禁止我在特定构造函数中使用placement new.

我喝咖啡多少,而且我没有看到明显的解决方案吗?

谢谢

c++ placement-new optional constexpr c++17

5
推荐指数
1
解决办法
353
查看次数

constexpr(但不是真的)构造函数在gcc中编译,但不在clang中编译

我正在玩constexprC++ 14及以上版本的构造函数,并注意到一些奇怪的东西.这是我的代码:

#include <iostream>
#include <string>

using std::cout;
using std::endl;

#define PFN(x) cout << x << __PRETTY_FUNCTION__ << endl
#define PF     PFN("")
#define NL     cout << endl

struct A {
    constexpr A() { PF; }
    virtual ~A() { PF; NL; }
};

struct B : A {
    constexpr B() { PFN(" "); }
    virtual ~B() { PFN(" "); }
};

int main(int argc, char** argv) {
    { A a; }
    { B b; }
    A* a = new …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang constexpr c++14

5
推荐指数
1
解决办法
405
查看次数

默认情况下,编译器是否生成构造函数constexpr?

以下代码可以使用clang ++ 3.8.0g ++ 7.2.0 成功编译(编译标记为):-std=c++14 -Wall -Wextra -Werror -pedantic-errors

struct Foo
{
    constexpr operator bool() const
    {
        return false;
    }
};


int main()
{
    constexpr bool b = Foo{};

    (void)b;
}
Run Code Online (Sandbox Code Playgroud)

编译器的这种行为是否符合标准?请注意,将任何成员(如int i;)添加到Foo都不会改变任何内容

c++ constructor language-lawyer constexpr c++14

5
推荐指数
1
解决办法
296
查看次数

constexpr变量是否需要“静态初始化顺序失败”?

如果我初始化constexpr变量foo在一个翻译单元,其具有非缺省值,然后一个初始化另一个constexpr变量barfoo在另一翻译单元有可能是bar之前被初始化foo导致bar,是由初始化为零或缺省初始化foo。即与在非constexpr情况下(静态初始化顺序彻底失败有效)不同,编译器和链接器是否将分析依赖性顺序以确保正确的结果?

另外,constexpr变量模板如何受到影响?在单个翻译单元中,它们的初始化顺序是不确定的。

首选C ++ 17标准答案。

更新:这是一个最小的示例。有用; 那就是问题所在。至此,我99%确信这可以通过静态初始化命令惨败(TSIOF)来解决。但是,由于该问题的极端,阴险性质,我需要确认这是可以的。我相信该代码不会受到TSIOF的困扰,因为在xh命令abx.cc转换单元中包含了yh 。但是,AFAIU有2个翻译单元:一个包含a,另一个包含b。此外,AFAI-sort-of-U对a错误的多重定义不会出现,因为static关键字具有内部链接,a仍然具有全局范围

编译为:

clang++ -std=c++17 x.cc y.cc  #or g++
Run Code Online (Sandbox Code Playgroud)

可能的输出:

in foo
Run Code Online (Sandbox Code Playgroud)

可能的输出:

assertion failed (core dumped)
Run Code Online (Sandbox Code Playgroud)

文件x.cc:

#include "x.h"
int main(){ assert(b == 42); foo(); }
Run Code Online (Sandbox Code Playgroud)

文件xh:

#pragma once
#include "y.h"
static constexpr int b = a+1;
Run Code Online (Sandbox Code Playgroud)

文件y.cc:

#include …
Run Code Online (Sandbox Code Playgroud)

c++ initialization global-variables constexpr

5
推荐指数
1
解决办法
414
查看次数

为什么编译时浮点计算可能与运行时计算的结果不同?

constexpr:Introduction中,发言者提到"编译时浮点计算可能与运行时计算的结果不同": 在此输入图像描述

原因与"交叉编译"有关.

老实说,我无法清楚地理解这个想法.恕我直言,不同的平台也可能有不同的整数实现.

为什么它只影响浮点数?或者我想念什么?

c++ floating-point floating-accuracy language-lawyer constexpr

5
推荐指数
1
解决办法
440
查看次数

为什么std :: launder是一个constexpr函数?

我想知道为什么std::launder是一个constexpr功能.是否有任何用例可以在编译时使用?

c++ pointers constexpr

5
推荐指数
1
解决办法
193
查看次数