小编cig*_*ien的帖子

在 C++ 非类型模板参数中使用 decltype(auto)

我正在学习 C++17decltype(auto)非类型模板参数的新功能。我写了一个简单的代码片段如下:

#include <type_traits>

template<decltype(auto) arg>
struct Foo {};

int
main()
{
    constexpr int x = 42;
    static_assert(std::is_same_v<Foo<42>, Foo<x>>);
}
Run Code Online (Sandbox Code Playgroud)

据我了解,Foo<42>应该与Foo<x>.

但是,该static_assert语句使用 clang++、MSVC 19.27 编译,但使用 GCC 10.2、MSVC 19.25 编译失败。

我的问题是:为什么编译器的行为不同?标准对此有何评论?

链接到编译器资源管理器:

铛++ https://godbolt.org/z/66M695

gcc https://godbolt.org/z/3v5Mhd

MSVC 19.25 https://godbolt.org/z/qP6v89

MSVC 19.27 https://godbolt.org/z/14aK5Y

c++ language-lawyer c++17 decltype-auto

23
推荐指数
2
解决办法
1147
查看次数

MSVC 无法返回可以复制但不能移动的对象

在摆弄复制省略时,我遇到了这种奇怪的行为:

class Obj {
 public:
  Obj() = default;

  Obj(Obj&&) = delete;
  Obj(const Obj&) { std::cout << "Copy" << std::endl; }
};

Obj f1() {
  Obj o;
  return o; // error C2280: move constructor is deleted
}

Obj f2() {
  Obj o;
  return Obj(o); // this however works fine
}

int main() {
  Obj p = f1();
  Obj q = f2();

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

GCC 和 Clang 接受此代码并且能够在两种情况下使用复制省略。

f1()MSVC 中抱怨它无法返回,o因为Obj删除了 的移动构造函数。但是,我希望它能够依靠复制构造函数。这是 MSVC 中的错误还是这种期望的行为(我不明白)和 GCC/Clang …

c++ visual-c++ language-lawyer copy-elision c++17

23
推荐指数
2
解决办法
904
查看次数

如何在 Macbook pro (M1) GPU 上运行 Pytorch?

我尝试在 Macbook pro 上使用 PyTorch 训练模型。它采用新一代苹果M1 CPU。但是,PyTorch 无法识别我的 GPU。

GPU available: False, used: False
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
Run Code Online (Sandbox Code Playgroud)

有谁知道有什么解决办法吗?

我已将所有库更新到最新版本。

gpu pytorch apple-m1

23
推荐指数
3
解决办法
5万
查看次数

Clang 和 GCC 对于重载函数模板是否不明确存在分歧

我正在尝试移植一些为 GCC (8.2) 编写的代码以供 Clang 编译:

#include <tuple>

struct Q{};

using TUP = std::tuple<Q>;


template<typename Fn>
inline
void feh(Fn&, const std::tuple<>*)
{}

template<typename Fn, typename H>
inline
void feh(Fn& fn, const std::tuple<H>*)
{
    fn(H{});
}

template<typename  Fn, typename H, typename... R>
inline
void feh(Fn& fn, const std::tuple<H, R...>*)
{
    fn(H{});
    using Rest = const std::tuple<R...>*;
    feh<Fn, R...>(fn, static_cast<Rest>(nullptr));
}

template<typename Tuple, typename Fn>
inline
void fe(Fn& fn, const Tuple  *  tpl =  nullptr)
{
    feh(fn, tpl);
}

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

c++ language-lawyer c++11

23
推荐指数
3
解决办法
1701
查看次数

擦除-删除习语如何与范围/受限算法一起使用?

我正在尝试将 c++20 约束算法用于擦除删除习语:

std::vector<int> v;
v.erase(std::unique(std::begin(v), std::end(v)), std::end(v));
Run Code Online (Sandbox Code Playgroud)

但是当我做一个简单的转换时:

v.erase(std::ranges::unique(v), std::end(v));
Run Code Online (Sandbox Code Playgroud)

我收到一个错误,参数erase不匹配:

error: no matching function for call to 'std::vector<int>::erase(std::ranges::borrowed_subrange_t<std::vector<int>&>, std::vector<int>::iterator)'
Run Code Online (Sandbox Code Playgroud)

如果第二个参数是 ,则会产生类似的错误std::ranges::end(v)

我怎样才能让它发挥作用?


该问题最初使用remove而不是unique,但是std::erase所有容器都过载了,这使得该特定用例的动机降低。

c++ c++20 std-ranges

18
推荐指数
3
解决办法
709
查看次数

如果使用 goto 将控制权转移到 if(false) 块会发生什么?

我想通过尝试解决一个困难的“嵌套条件”问题来考虑以下代码:

goto error;
    
if (false)
{
error:
    cout << "error block" << endl;
}
else
{
    cout << "else block" << endl;
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,仅error block按预期显示(我猜?)。但这是所有编译器都定义的行为吗?

c++ goto language-lawyer

18
推荐指数
1
解决办法
972
查看次数

是否有规定在函数模板显式专业化中指定对“返回类型”的限制?

template<class T>
void fun(T){}

template<>
int fun(int){return 0;}
Run Code Online (Sandbox Code Playgroud)

考虑这个例子,它被所有实现拒绝。但是,我在当前标准中没有发现任何有说服力的条款来指定这种显式专业化声明的格式不正确。如果存在的话,规则是什么?

此外,潜在的相关规则可能是[temp.deduct.decl#2]

如果对于如此考虑的一组函数模板,在考虑部分排序后没有匹配或有多个匹配([temp.func.order]),则推导失败,并且在声明情况下,程序有问题-形成。

我认为“匹配”的含义在这里还不够明确,因为“匹配”没有明确定义任何内容。

c++ templates language-lawyer explicit-specialization

18
推荐指数
2
解决办法
298
查看次数

范围适配器的开始/结束的常量过载是否受到限制?

在 C++20 中,某些范围同时具有const和 non- const begin()/end(),而其他范围仅具有 non- const begin()/end()

\n

为了使包装前者的范围适配器能够begin()/end()在合格时使用const,一些范围适配器如elements_viewreverse_viewcommon_view都提供了 constrainedconst合格的begin()/end()函数,例如:

\n
 template<view V>\n   requires (!common_\xc2\xadrange<V> && copyable<iterator_t<V>>)\n class common_view : public view_interface<common_view<V>> {\n  public:\n   constexpr auto begin();\n   constexpr auto end();\n\n   constexpr auto begin() const requires range<const V>;\n   constexpr auto end()   const requires range<const V>;\n};\n\ntemplate<input_\xc2\xadrange V, size_t N>\n  requires view<V> && has-tuple-element<range_value_t<V>, N>\nclass elements_view : public view_interface<elements_view<V, N>> {\n public:\n  constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++20 std-ranges

17
推荐指数
1
解决办法
699
查看次数

`constexpr` 和 `#define` 之间的区别

所以我读了关于constexpr 和 const 之间有什么区别的有趣答案,但我很好奇 #define 和 constexpr 之间有什么区别?我觉得 constexpr 只是一个可以选择类型的#define。

c++ macros constexpr

16
推荐指数
2
解决办法
2万
查看次数

在将 constexpr 添加到语言后,将变量声明为 const 是多余的吗?

正如关键字constexpr所暗示的const,它也可以在编译时计算,这是否意味着现在将变量声明为const没有意义,我们应该始终将它们声明为constexpr

c++ constants constexpr c++11

15
推荐指数
3
解决办法
279
查看次数