小编Ric*_*ten的帖子

模板参数类型 `void` 与显式使用 `void`

下面的代码中,为什么模板函数的显式扩展foo无法编译,而 的扩展却bar编译成功?实时链接 - https://godbolt.org/z/o8Ea49KEb

\n
template <typename T1, typename T2>\nT1 foo(T2) { T2(42); return T1{}; };\n\ntemplate <typename T1, typename T2>\nT1 bar(void) { T2(42); return T1{}; };\n\nint main()\n{\n    foo<int, void>();    // fails\n\n    bar<int, void>();    // works\n}\n
Run Code Online (Sandbox Code Playgroud)\n

T2请注意,两个函数的主体中都使用了模板参数,唯一的区别是函数参数 tobar已被手动替换。

\n

这个问题是在阅读std::conditional - Invalid argument type \xe2\x80\x98void\xe2\x80\x99 即使在测试 \'void\'并试图简化问题时受到启发的。

\n

c++

19
推荐指数
2
解决办法
2201
查看次数

部分特化类的成员定义

我正在尝试定义部分专门化的类模板的成员函数,但是不同的编译器对我可以做什么以及为什么有截然不同的看法。

让我们慢慢来,从适用于所有主要编译器(all = gcc、clang 和 msvc)的东西开始:

#include <concepts>
#include <type_traits>

template <class T>
concept Integer
= std::is_same_v<T,int> || std::is_same_v<T,unsigned int>;

template <class T>
concept FloatingPoint
= std::is_same_v<T,float> || std::is_same_v<T,double>;


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

template <Integer T>
struct Foo<T>
{
    T get(){ return 0; }
};

template <FloatingPoint T>
struct Foo<T>
{
    T get(){ return 0; }
};

int main()
{
    Foo<char>().get();
    Foo<int>().get();
    Foo<float>().get();
}
Run Code Online (Sandbox Code Playgroud)

Godbolt 上的示例:gccclangmsvc

很酷,但我想将成员函数的声明和定义分开。让我们将定义移到专门的类之一 …

c++ partial-specialization visual-c++ language-lawyer c++-concepts

11
推荐指数
1
解决办法
245
查看次数

保证重新排序矢量

说我有这个代码:

#include <iostream>
#include <vector>

int main() 
{
    std::vector<int> vec {10, 15, 20};
    auto itr = vec.begin();
    vec.erase(itr);
    for(const auto& element : vec)
    {
        std::cout << element << " ";
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给了我15 20预期的效果.现在,cppreference说erase():

在擦除点或之后使迭代器和引用无效,包括end()迭代器

很公平,但这是标准给出的唯一保证vector::erase()吗?

是否允许在擦除的迭代器之后重新排序它的元素?

例如,这些条件是否保证在擦除后保持,这意味着erase()迭代器之后的所有元素都向左移1:

vec[0] == 15
vec[1] == 20
Run Code Online (Sandbox Code Playgroud)

或者允许实现在他们认为合适的情况下移动值,从而创建场景vec[0] == 20等等?

我想引用标准的相关部分.

c++ vector language-lawyer

10
推荐指数
2
解决办法
565
查看次数

从多个线程调用 `std::shared_future&lt;T&gt;::wait`

cppreference明确表示std::shared_future<T>::wait从多个线程调用:

从多个线程在同一个 std::shared_future 上调用 wait 是不安全的;预期用途是等待相同共享状态的每个线程拥有 std::shared_future 的副本。

但我找不到这种说法的依据。标准标记中没有任何wait特殊情况。虽然标准说单个shared_future实例上的方法不同步,但你不需要同步,只要只调用 const 方法:

[17.6.5.9/3] C++ 标准库函数不应直接或间接修改当前线程以外的线程可访问的对象 (1.10),除非这些对象是通过函数的非常量参数直接或间接访问的,包括 this。

矛盾的 答案上的SO被发现。有没有人有这方面的权威来源,可以解释如何const在 stdlib 上调用方法会导致竞争条件?

c++ multithreading thread-safety language-lawyer

7
推荐指数
0
解决办法
143
查看次数

你可以从C的任何地方收获和恢复Luajit协同程序吗?

我试图想出一个解决方案,从C函数中产生一个Luajit协程,它立即创建一个要在另一个OS线程上处理的tasklet.

根据Lua的各种文件,事情开始相互矛盾,这是不是完全有可能?文件不是很清楚,也没有解释推理.

Lua 5.1声明每个协程都有一个堆栈.但是,只有一个全局C堆栈.我不完全确定为什么这是一个障碍.

Lua 5.2显然用lua_pcallk和lua_yieldk修复了这个问题.但这些解释非常令人困惑.

但是这些都没有说明我正在使用的VM ......这是LuaJIT 2.0.4和LuaJIT 2.1.0.

谷歌搜索告诉我,Luajit 1.x已经实现了CoCo,显然每个lua线程(协同程序)都使用了真正的C堆栈.这允许从任何地方屈服.

只有一个搜索引导我看到显然LuaJIT 2.x没有实现coco,因为每个协程都使用C堆栈.

谁能告诉我从C产生协同程序的问题是什么?并验证我是否可以安全地从c产生/恢复luajit 2.x协同程序?

c lua multithreading coroutine luajit

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

使用String.format格式化SSN

我目前正在使用随机发生器为我生成9位数字.我目前正在尝试在java中使用String.format来打印像XXX-XX-XXXX这样的随机数字,就像社会安全号码一样.我只是不能这样做,我不知道该怎么办.我正在使用模数,似乎我的填充关闭或我完全错了.问题是我必须使用模数.非常感谢任何帮助我指向正确方向的帮助,谢谢.我正在尝试修复ID.

public  String toString (){

        System.out.printf("%d\n",ID);

        return  String.format("First Name: %12s LastName %12s ID: %03d-%02d-%04d ", firstName, lastName,ID%1000,ID%10000, ID%000001000);

    }
}
Run Code Online (Sandbox Code Playgroud)

java string.format

5
推荐指数
2
解决办法
2363
查看次数

std::launder 的效果是否在调用它的表达式之后持续?

考虑以下示例代码:

struct X { const int n; };
union U { X x; float f; };
void fun() {
  U u = {{ 1 }};
  u.f = 5.f;               // OK, creates new subobject of 'u'
  X *p = new (&u.x) X {2}; // OK, creates new subobject of 'u'
  
  if(*std::launder(&u.x.n) == 2){// condition is true because of std::launder
    std::cout << u.x.n << std::endl;  //UB here?
    }
}
Run Code Online (Sandbox Code Playgroud)

函数会fun根据语言标准打印什么?换句话说,std::launderlast 的效果是否超出了它被调用的表达式?std::launder或者,我们每次需要访问更新后的值时都必须使用u.x.n?

c++ compiler-optimization language-lawyer stdlaunder

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

C++ 11中的逗号运算符(排序)

标准提到f(a,(t = 3,t + 2),c); 根据我的理解,这将是赋值表达式,后跟第二个运算符的表达式.

但语法列出并列:

表达:

赋值表达式

表达式,赋值表达式

编程语言标准C++修订版N4140(2014年11月)

有人这么好,向我解释一下,我在这里错过了什么?

c++ language-lawyer sequencing c++11 c++14

4
推荐指数
2
解决办法
417
查看次数

捕获而不尝试成功编译

以下代码使用g ++版本5.1.0成功编译.注意在成员函数中catch没有对应tryfoo::bar().我想知道这种语法是否合法,如果有,它有什么影响?

struct foo
{
  void bar()
  {
  }
  catch (...)
  {
  }
};

int main ()
{
  foo f;
  f.bar();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

最初在构造函数中看到Catch块而没有尝试

c++ language-lawyer

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

C++ 对象(标准定义)是否保留在内存映射文件中?

问题的启发来自处理大型数据二进制文件

链接到对象

程序(1)创建一个内存映射文件并向其中写入一些对象(C++标准定义),关闭文件并退出。

程序(2)将上述文件映射到内存中并尝试通过reinterpret_cast.

根据标准,这是否合法,因为对象表示没有更改并且对象仍然存在于文件中?

如果在两个进程之间尝试这样做,而不是使用文件,而是使用共享进程内存,这合法吗?

注意 - 这个问题与存储或共享本地虚拟地址无关,因为这显然是一件坏事。

c++ language-lawyer

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

为什么包含 &lt;map&gt; 会导致 div 函数被定义在全局命名空间中?

考虑以下代码块:

void foo(){
  int a = div(1,2);
}
Run Code Online (Sandbox Code Playgroud)

这通常不会编译,因为该div函数尚未声明。但是,如果我在代码前面加上#include <map>,代码就会编译。为什么要将map标识符拉入全局命名空间,以及为什么div特别使用该函数?有办法避免这种情况吗?

[麦克维]

#include <map>

void foo(){
  int a = div(1,2);
}

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

实时链接 - https://godbolt.org/z/Ye8rv4MTc

铿锵——<source>:4:7: error: no viable conversion from 'div_t' to 'int'

海湾合作委员会-<source>:4:11: error: 'div' was not declared in this scope

MSVC-<source>(4): error C2440: 'initializing': cannot convert from 'div_t' to 'int'

c++ gcc

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