小编Joh*_*qua的帖子

constexpr std :: initializer_list的编译时验证

我正在尝试实现一些硬编码值的编译时验证.我有以下简化尝试:

using Type = std::initializer_list<int>;

constexpr bool all_positive(const Type& list)
{
    bool all_positive = true;
    for (const auto& elem : list)
    {
        all_positive &= (elem > 0);
    }
    return all_positive;
}

int main()
{
    static constexpr Type num_list{ 1000, 10000, 100 };

    static_assert(all_positive(num_list), "all values should be positive");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

gcc编译它并完全按照我的预期工作,但是clang无法编译错误:

static_assert_test.cc:79:16: error: static_assert expression is not an integral constant expression
    static_assert(all_positive(num_list), "all values should be positive");
                  ^~~~~~~~~~~~~~~~~~~~~~
static_assert_test.cc:54:20: note: read of temporary is not allowed in a constant …
Run Code Online (Sandbox Code Playgroud)

c++ c++14

12
推荐指数
1
解决办法
647
查看次数

模板变量的显式特化

类似这个问题有关模板类的静态常量类成员明确分工,以及这个问题对模板类的明确分工,但我的问题是具有可变模板的显式特。

我的 MCVE:

//my_templated_literal.h
#pragma once

template <typename T>
constexpr T val;
Run Code Online (Sandbox Code Playgroud)
//my_specialised_literal.h
#pragma once

#include "my_templated_literal.h"

template <>
constexpr int val<int> = 2;
Run Code Online (Sandbox Code Playgroud)
//my_specialised_literal.h
#pragma once

#include "my_templated_literal.h"

template <>
constexpr int val<int> = 2;
Run Code Online (Sandbox Code Playgroud)
//main.cc
#include "my_specialised_literal.h"

int main() {}
Run Code Online (Sandbox Code Playgroud)

编译命令:$CXX -std=c++14 my_specialised_literal.cc main.cc 这可以编译并且似乎在我尝试过的几乎每个编译器版本上都按预期工作,但是会在使用 clang-9 时出现链接器错误:

/tmp/main-ec49c7.o:(.rodata+0x0):`val'的多重定义

/tmp/my_specialised_literal-521691.o:(.rodata+0x0): 这里首先定义

这是大多数编译器版本默默接受的 ODR 违规,还是 clang-9 在某种程度上是错误的?如果是前者,我知道如果我可以使用 C++17,我可以通过进行 specialization 来修复它inline,但是什么是 C++14 修复问题?

c++ templates linker-errors explicit-specialization c++14

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

在 constexpr 函数中断言

在尝试找出为什么会出现某个编译错误时,我想出了以下最小示例:

\n\n
constexpr void Test(bool test)\n{\n    if (test)\n        return;\n\n    assert(false);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我尝试过的每个版本的 clang (3.7+) 都可以毫无问题地进行编译,但使用 gcc 会失败(测试了 5-8),

\n\n
\n

错误:调用非\xe2\x80\x98constexpr\xe2\x80\x99函数\xe2\x80\x98void __assert_fail(const\n char*, const char*, unsigned int, const char*)\xe2\x80\x99

\n
\n\n

根据我的理解,该函数应该能够constexpr,因为可以在编译时评估该函数的一组参数值。

\n\n

是我的理解错误,还是gcc编译失败而错误?

\n

c++ constexpr

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

gcc size_t and sizeof arithmetic conversion to int

I decided to test compile a project with -Wsign-conversion enabled, to see what warnings would come up, and came across something that doesn't seem right, where gcc behaves differently than clang. Can someone please tell me which is correct?

I have a function that takes a size_t param:

void func(size_t) {}
Run Code Online (Sandbox Code Playgroud)

some other struct

struct Test {};
Run Code Online (Sandbox Code Playgroud)

and calling code

int i = some_initialiser();
func(sizeof(Test) + static_cast<size_t>(i));
Run Code Online (Sandbox Code Playgroud)

So from my understanding, sizeof returns size_t, and arithmetic between two variables …

c++ gcc-warning implicit-conversion

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