小编W.F*_*.F.的帖子

使用纯属性注释const成员函数

状态的gcc文档__attribute__((pure)):

除返回值外,许多函数都没有效果,它们的返回值仅取决于参数和/或全局变量.这样的函数可以像算术运算符那样经受公共子表达式消除和循环优化.应使用属性声明这些函数pure.

仅依赖于参数意味着什么?考虑:

struct Wrapper {
    int i;

    int get() const { return i; }
    void set(int x) { i = x; }
};
Run Code Online (Sandbox Code Playgroud)

标记Wrapper::get()pure成员函数是否有效?它只取决于隐式Wrapper实例,但数据可能会改变.

c++ gcc

15
推荐指数
1
解决办法
507
查看次数

有没有办法在c ++中推导出一个数组元素的类型

我在推导一个c ++数组的单个元素的类型时遇到了问题.

我想做到这样的事情:

template <class T>
struct array_element { };

template <class T>
struct array_element<T[]> {
   using type = T;
};

int main() {
   int a[5] = {1, 2, 3, 4, 5};
   array_element<decltype(a)>::type element = a[0];
}
Run Code Online (Sandbox Code Playgroud)

但是代码显然不能编译(int [5]与T []不匹配)...

c++ templates sfinae type-traits c++11

14
推荐指数
2
解决办法
1161
查看次数

构造函数模板可以在类模板的c ++ 17参数推导中导致歧义

考虑一个简单的例子:

template <class T>
struct foo {
    template <template <class> class TT>
    foo(TT<T>&&) {}
    foo(foo<T>&&){}
    foo() {}
};

int main() {
    foo      f1(foo<int>{}); //case 1.
    foo<int> f2(foo<int>{}); //case 2.
}
Run Code Online (Sandbox Code Playgroud)

情况1.在clang中的foo类的模板参数推导中导致模糊,但在gcc中没有.我认为模板函数(这里 - 构造函数)在重载决策中具有较低的优先级.这不是这种情况吗?

错误信息:

prog.cc:10:14: error: ambiguous deduction for template arguments of 'foo'
    foo      f1(foo<int>{}); //case 1.
             ^
prog.cc:4:5: note: candidate function [with T = int, TT = foo]
    foo(TT<T>&&) {}
    ^
prog.cc:5:5: note: candidate function [with T = int]
    foo(foo<T>&&){}
    ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

[铿锵演示] [gcc演示]

c++ templates language-lawyer template-argument-deduction c++17

14
推荐指数
1
解决办法
358
查看次数

有没有办法将std :: move std :: string转换为std :: stringstream

在c ++引用中,我没有看到std::stringstream构造函数接受rvalue引用std::string.是否有任何其他辅助函数将字符串移动到字符串流而没有开销,或者是否有一个特殊的原因来制定这样的限制?

c++ move-semantics c++11 c++14

13
推荐指数
2
解决办法
1188
查看次数

使用外部类的可变参数模板中的args部分特化可变参数模板内部类是否合法

考虑一下代码:

#include <iostream>

template <class... Ts>
struct outer {
   template <class... ITs>
   struct inner {
      static constexpr bool value = false;
   };

   template <class... ITs>
   struct inner<Ts..., ITs...> {   
      static constexpr bool value = true;
   };
};

int main() {
   std::cout << outer<int, float, double>::inner<int, float, double, int>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

代码用clang ++编译但不用g ++编译产生错误:

temp3.cc:11:11:错误:参数包参数'Ts ...'必须位于模板参数列表的末尾

struct inner<Ts..., ITs...> {
       ^
Run Code Online (Sandbox Code Playgroud)

正如我已经在这里建立的那样,内部阶级的部分专业化应该是合法的.

编辑: 为了完整性,值得补充一点,上面代码的clang警告他可能在推导IT参数时遇到问题,但没有任何问题......

c++ templates template-specialization variadic-templates c++11

13
推荐指数
1
解决办法
321
查看次数

用户定义的数字文字可以紧跟一个点吗?

从C++ 11开始,就可以创建用户定义的文字.正如预期的那样,可以从这些文字返回复杂的结构.但是,在尝试使用此类运算符时123_foo.bar():

struct foo {
    int n;
    int bar() const { return n; }
};

constexpr foo operator ""_foo(unsigned long long test)
{
    return foo{ static_cast<int>(test) };
}

int main() {
    return 123_foo.bar();
}
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会和克朗拒绝了,说他们找不到operator""_foo.bar.MSVC接受它.如果我改为写123_foo .bar(),那么所有三个编译器都接受它

谁在这?是123_foo.bar()以往任何时候都有效吗?


一些额外的信息:


我倾向于认为这是一个GCC和Clang错误,因为.它不是有效标识符的一部分.

c++ language-lawyer user-defined-literals c++11

13
推荐指数
1
解决办法
421
查看次数

为什么lambda在转换为函数指针时不能在constexpr上下文中使用?

考虑一个例子:

template <void (*Foo)()>
struct S {
};

int main() {
    struct A {
        static void x() { }
    };
    S<&A::x> s;
}
Run Code Online (Sandbox Code Playgroud)

代码在clang中编译,gcc认为x没有链接...对于非常类似的例子,只是在使用lambda表达式时:

template <void (*Foo)()>
struct S {
};

int main() {
    auto lambda = []{};
    S<+lambda> s;
}
Run Code Online (Sandbox Code Playgroud)

gcc和clang都同意不编译代码:根据gcc,由unary +返回的函数没有链接,相反,clang状态表示对该函数的强制转换操作符未声明为constexpr.是否有任何理由不允许lambda强制转换为在constexpr上下文中使用的函数指针?

查找编译器和现场演示产生的以下错误:

gcc:

prog.cc:7:14:错误:'main():::: _ FUN'不是类型'void(*)()'的有效模板参数,因为'static constexpr void main():::: _ FUN( )'没有联系

clang:

prog.cc:7:8:注意:非constexpr函数'operator void(*)()'不能用于常量表达式

c++ lambda language-lawyer constexpr

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

在fold表达式中使用lambdas时出现"未初始化的捕获引用"错误 - clang vs gcc

请考虑以下代码:

template <typename F, typename X0, typename X1, typename... Xs>
auto fold_left(F&& f, X0&& x0, X1&& x1, Xs&&... xs)
{
    auto acc = f(x0, x1);
    return ([&](auto y){ return acc = f(acc, y); }(xs), ...);
}

const std::string a{"a"}, b{"b"}, c{"c"}, d{"d"}, e{"e"};
const auto cat = [](auto x, auto y) { return "(" + x + ", " + y + ")"; };
Run Code Online (Sandbox Code Playgroud)

在调用和打印时fold_left(cat, a, b, c),g ++ 7和clang ++ 5输出:

((a,b),c)


当调用和打印fold_left(cat, a, b, c, …

c++ language-lawyer fold-expression c++17

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

如果结构化绑定不能是constexpr,为什么它们可以在constexpr函数中使用?

根据这个答案,显然没有充分的理由说明为什么不允许结构化绑定是constexpr,但标准仍然禁止它.但是,在这种情况下,是否应该禁止在constexpr函数中使用结构化绑定?考虑一个简单的片段:

#include <utility>

constexpr int foo(std::pair<int, int> p) {
    auto [a, b] = p;
    return a;
}

int main() {
    constexpr int a = foo({1, 2});
    static_assert(a == 1);
}
Run Code Online (Sandbox Code Playgroud)

无论GCC不惹麻烦编译代码.代码是否格式不正确或实际允许这个?

c++ language-lawyer constexpr c++17 structured-bindings

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

用户定义的演绎指南是否涉及模板模板参数作为符合指导标准的模板

背景

昨天我问了一个关于模板模板参数的扣除指南使用保证的问题.当Barry改变了对代码标准符合性确认的答案时,我感到非常惊讶.令我惊讶的是,实际上并不是因为扣除指南可以应用于模板模板参数,而是来自符合此合规性的标准部分,即[temp.param]/3:

标识符不遵循省略号的类型参数将其标识符定义为模板声明范围内的typedef-name(如果未声明template)或template-name(如果声明template).

加上[temp.deduct.guide]/1simple-template-id规则可以创建一个接受任何模板的通用推理指南.

#include <string>

template <class T>
struct Foo {
   Foo(T) { }
};

template <template <class> class TT>
TT(const char *) -> TT<std::string>;

int main() {
    Foo foo("abc");
}
Run Code Online (Sandbox Code Playgroud)

这个问题

代码导致gcc因内部错误而崩溃,并导致clang中的编译错误.说实话,我并不是说代码应该在C++中实际允许,但认为当前的措辞确实使它符合要求.我错过了一些不允许代码的重要规则吗?

c++ template-templates language-lawyer template-argument-deduction c++17

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