相关疑难解决方法(0)

将constexpr数组扩展为一组非类型模板参数

假设我有一个编译时constexpr数组和一个可变参数类模板,其中包含一组与数组元素相同类型的非类型参数.

我的目标是使用数组中的值实例化类模板:

struct Container
{
    int containee[3];
};

constexpr Container makeContainer();

template <int... Elements> class Foo;

Foo<makeContainer().containee[0],
    makeContainer().containee[1],
    makeContainer().containee[2]> foo;
Run Code Online (Sandbox Code Playgroud)

上面的代码效果很好.但是,每当我需要实例化Foo模板时,我都不得不手动索引数组.我想编译器自动为我做这件事:

Foo<Magic(makeContainer().containee)> foo;
Run Code Online (Sandbox Code Playgroud)

我在cppreference做了一些RTFM,但这没有帮助.我知道std::forward<>(),但它不能应用于模板参数列表.

c++ templates template-meta-programming variadic-templates constexpr

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

在clang中显式指定的参数无效但在gcc中成功编译 - 谁错了?

以下代码在g ++中编译时没有问题:

#include <iostream>
#include <string>
#include <tuple>

template<typename T>
void test(const T& value)
{
    std::tuple<int, double> x;
    std::cout << std::get<value>(x);
}

int main() {
    test(std::integral_constant<std::size_t,1>());
}
Run Code Online (Sandbox Code Playgroud)

我使用了这个命令:

g++ test.cpp -o test -std=c++14 -pedantic -Wall -Wextra
Run Code Online (Sandbox Code Playgroud)

但是当我切换g++到clang++(使用g ++ 5.1.0和clang ++ 3.6.0)时,我收到以下错误:

test.cpp:9:18: error: no matching function for call to 'get'
    std::cout << std::get<value>(x);
                 ^~~~~~~~~~~~~~~
test.cpp:13:5: note: in instantiation of function template specialization 'test<std::integral_constant<unsigned long, 1> >' requested here
    test(std::integral_constant<std::size_t,1>());
         ^~~~~~~~~~~~~~~
<skipped>

/usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0/../../../../include/c++/5.1.0/tuple:867:5: note: candidate template ignored: …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates clang

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

为什么引用上的constexpr函数不是constexpr?

考虑以下功能:

template <size_t S1, size_t S2>
auto concatenate(std::array<uint8_t, S1> &data1, std::array<uint8_t, S2> &data2) {
    std::array<uint8_t, data1.size() + data2.size()> result;

    auto iter = std::copy(data1.begin(), data1.end(), result.begin());
    std::copy(data2.begin(), data2.end(), iter);

    return result;
}

int main()
{
    std::array<uint8_t, 1> data1{ 0x00 };
    std::array<uint8_t, 1> data2{ 0xFF };

    auto result = concatenate(data1, data2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当使用clang 6.0编译时,使用-std = c ++ 17,此函数无法编译,因为数组上的size成员函数不是constexpr,因为它是一个引用.错误消息是这样的:

错误:非类型模板参数不是常量表达式

当参数不是引用时,代码按预期工作.

我想知道为什么会这样,因为size()实际上返回一个模板参数,它几乎不再是const.参数是否是参考不应该有所作为.

我知道我当然可以使用S1和S2模板参数,该功能仅仅是问题的简短说明.

标准中有什么吗?我很惊讶地发现了编译错误.

c++ language-lawyer constant-expression

7
推荐指数
3
解决办法
216
查看次数

使用局部变量的引用来初始化 constexpr 变量是否有效?

以下代码只能在 GCC 上编译(在 godbolt.org 上检查了 10.4 和 13.2),但不能在 Clang 上编译(在我尝试过的所有版本上都失败,例如 godbolt.org 上的 17.0.1):

struct A {
  static constexpr int b{1};
};

int main(int argc, char *argv[]) { 
    A a;
    A& aref{a};
    constexpr auto bb1{a.b};
    constexpr auto bb2{aref.b};
    return bb1+bb2; 
}
Run Code Online (Sandbox Code Playgroud)

叮当输出:

struct A {
  static constexpr int b{1};
};

int main(int argc, char *argv[]) { 
    A a;
    A& aref{a};
    constexpr auto bb1{a.b};
    constexpr auto bb2{aref.b};
    return bb1+bb2; 
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/nG4j3KefE

为什么?

c++ clang language-lawyer constexpr

7
推荐指数
1
解决办法
318
查看次数