小编wim*_*aan的帖子

静态 constexpr 模板成员在专门化时给出未定义的引用

以下代码给出了未定义的引用链接错误:

template<int>
struct X {
    static constexpr int x = 0;
};

template<>
constexpr int X<1>::x;

int main() 
{   
    return X<1>::x;
}
Run Code Online (Sandbox Code Playgroud)

但我不知道确切的原因。

是否可以在不专门化整个模板的情况下定义数据成员?

需要明确的是:这段代码编译得很好,但会出现链接器错误(未定义引用)。

c++ templates linker-errors constexpr

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

如何防止 GCC 为静态成员生成防护

以下是一个有时生成警卫有时不生成的最小示例:

struct A {
    inline A(int v = 0) {} // without ctors, guards are omitted
    int m1() const {
        return m;
    }
private:
    int m = 0;
};

//namespace { // without anon-ns guards are generated 
    template<typename T>
    struct X {
        static int foo() {
            // static T m; // even as local-static and -fno-threadsafe-statics, guards are generated 
            return m.m1();
        }
        inline static T m; // comment this and uncomment above to try as local-static
    };
//}

int main() …
Run Code Online (Sandbox Code Playgroud)

c++ static gcc g++ compiler-optimization

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

如果constexpr(条件)为编译时条件

我想使用constexpr bool(useF在下面的示例中)来启用以下代码中的功能.在这里,打电话A::f().另外,我希望在关闭该功能的情况下成为alias-template(a)void.

我试图使用constexpr if语句,但是主体仍在实例化,这会导致编译错误.如果我使用包装器模板(X),正如我预期的那样丢弃了正文,但这对我来说似乎很难看.有没有其他方法可以做到这一点?

constexpr bool useF = false;

struct A {
    static void f() {}
};

using a = std::conditional<useF, A, void>::type;

template<typename L>
struct X {
    static void h() {
        if constexpr(std::is_same<L, A>::value) {
            L::f(); // not instantiated, no error
        }
    }
};

int main() {
    if constexpr(useF) {
        a::f(); // error!?
    }

    X<a>::h();
}
Run Code Online (Sandbox Code Playgroud)

我正在使用g ++ - 7.0.1和-std = c ++ 17

c++ c++17 if-constexpr

4
推荐指数
1
解决办法
1173
查看次数

lambda表达式中ref-captured和非显式捕获的constexpr变量之间的区别

这个问题在没有捕获的情况下访问lambda表达式中的constexpr变量回答了为什么下面示例中的ref-capture不是严格必要的.但另一方面,如果被捕获,则会收到错误.

这个错误似乎是由递归本质引发的foo().

template<typename T>
constexpr int bar(const T& x) { // NOK
//constexpr int bar(T x) { // OK
    return x;
}

template<typename T>
int foo(const T& l) {
    constexpr auto x = l() - 1;
    auto y = [&]{return bar(x);}; // if ref-capture is used, the above bar(const T&) is NOK, why? 

    if constexpr(x <= 0) {
        return 42;
    }
    else {
        return foo(y);
    }
}

auto l2 = []{
    return 3;
};

int main() …
Run Code Online (Sandbox Code Playgroud)

c++ lambda language-lawyer c++17

4
推荐指数
1
解决办法
115
查看次数

无法识别C++文字运算符模板

为什么不识别以下文字运算符模板?

template<char... Chars>
constexpr int operator"" _p(){
    return 0;
}

int main()
{
    int  fs1 = "123"_p;
}
Run Code Online (Sandbox Code Playgroud)

更新: 感谢我现在使用的答案:

#include <avr/pgmspace.h>

template<typename C, C... CC>
struct PgmString {
    static constexpr const char* str(){
        return &data[0];
    }
    static constexpr const char data[] PROGMEM = {CC..., '\0'};
};
template<typename C, C... CC>
constexpr const char PgmString<C, CC...>::data[] PROGMEM;

template<typename C, C... CC>
constexpr PgmString<C, CC...> operator"" _pgm(){
    return PgmString<C, CC...>();
}
Run Code Online (Sandbox Code Playgroud)

这会将字符串放入AVR微控制器的闪存中.但是如果我将文字字符串长度增加一个字符,则使用的闪存大小会增加两(!)个字节.

c++ literals

3
推荐指数
2
解决办法
449
查看次数

参数包扩展的编译时反转

在下面的类模板我想initalize成员阵列b与参数组的值vv反奥得

template<typename T>
struct Test {
public:
    template<typename... B>
    explicit Test(B... vv) : b{vv...,} // how to initialize member b with pack expansion v... in reverse order
    {
    }
private:
    std::byte b[sizeof(T)];
};
Run Code Online (Sandbox Code Playgroud)

我无法想象如何在表单中反转参数包扩展,它也可以在初始化列表中使用。

c++ variadic-templates

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

具有约束/概念的类模板专业化

我尝试使用约束进行类专门化:

struct A {};
struct B {};
struct C {};

template<typename T>
concept bool AorB() {
    return std::is_same<T, A>::value || std::is_same<T, B>::value;
}

template<typename T>
class X {};

template<AorB T>
class X {};

int main() {
    X<A> x1; // error: redeclaration 'template<class T> class X' with different constraints class X {};
    X<B> x2;
    X<C> x3;
}
Run Code Online (Sandbox Code Playgroud)

我不知道我在这里犯了错误,或者这一般是不可能的?

有什么可以替代这种方法?我可以使用CRTP到一个公共基本模板的专业化,但这对我来说看起来很难看.

c++ c++-concepts c++17

2
推荐指数
1
解决办法
230
查看次数

结合两个几乎相同的类模板

下面是两个大多数相同的模板PgmArrayPgmArrayF.第一个适用于lvalue-ref模板参数,第二个适用于积分参数.我喜欢将这两者合二为一:

#include <stdint.h>
#include <type_traits>
#include <array>
#include <iostream>

template<typename T, const T&... Ts>
struct PgmArray final {
    static constexpr uint8_t size = sizeof... (Ts);
    static constexpr T data[] {Ts...};
};

template<typename T, T... Ts>
struct PgmArrayF final {
    static constexpr uint8_t size = sizeof... (Ts);
    static constexpr T data[] {Ts...};
};

struct A{
    uint8_t m = 0;
};

constexpr A a1{1};
constexpr A a2{2};

constexpr auto x1 = PgmArray<A, a1, a2>{}; // ok
constexpr auto …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates c++17

2
推荐指数
1
解决办法
97
查看次数

NTTP 的结构类型:为什么所有成员都必须是公共的?

在下面的例子中

template<auto V>
struct A {};

struct B {
    constexpr B(int a) : value{a} {}
private:
    int value{0};
};

int main() {
    constexpr B b{0};
    A<b> t2;        
}
Run Code Online (Sandbox Code Playgroud)

成员value必须是公共的才能使类型B结构化以将其用作 NTTP for A.

那么,没有可以用作 NTTP 的具有私有成员的类型吗?这是http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1907r1.html的真正意图吗?

c++ templates c++20

2
推荐指数
1
解决办法
471
查看次数

使用“struct S”或“S”作为类型名的区别

在 C 语言中,结构化类型的名称S是 ist struct S

在 C++ 中,也可以用作struct S类型名,而不是像S平常那样使用 for

struct S {};

struct S s1; // also ok in C++
S s2; // normal way in C++
Run Code Online (Sandbox Code Playgroud)

因此,假设在 C++ 中使用struct SorS作为类型名是一个品味问题;-)

但下面的例子中有一些地方struct S是不允许的:

struct S1 {
    S1(int x = 0) : x{x} {}
    int x{};
};

typedef S1 S2;

template<typename T>
auto foo(T a) {
//    T::_; // T is deduced to `S` in all …
Run Code Online (Sandbox Code Playgroud)

c++ constructor struct declaration

2
推荐指数
1
解决办法
150
查看次数