小编Dr.*_*Gut的帖子

为什么我们不能专门化概念?

适用于类的语法不适用于概念:

template <class Type>
concept C = requires(Type t) {
    // ...
};


template <class Type>
concept C<Type*> = requires(Type t) {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

MSVC 对于“专业化”行的说法是:error C7606: 'C': concept cannot be explicitly instantiated, explicitly specialized or partially specialized

为什么概念不能专门化?有理论上的原因吗?

c++ template-specialization c++-concepts c++20

25
推荐指数
3
解决办法
3198
查看次数

安装 Visual Studio 后,我可以从根目录移动或删除 appverifUI.dll 和 vfcompat.dll 吗?

我最近安装了 Visual Studio 和 Visual Studio Code,这两个 .dll 文件留在我的C:\文件夹中。两者均由微软签署。他们在那里有什么理由吗?它们可以移动或删除吗?

这些文件是:

  • C:\appverifUI.dll
  • C:\vfcompat.dll

Visual Studio 和 Visual Studio Code 都是官方网站的最新版本。

我认为它们是安装过程中留下的,应该由安装程序移动/删除,但我不确定。

visual-studio visual-studio-code

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

为什么不使用时分配堆栈内存?

考虑以下示例:

struct vector {
    int  size() const;
    bool empty() const;
};

bool vector::empty() const
{
    return size() == 0;
}
Run Code Online (Sandbox Code Playgroud)

生成的汇编代码vector::empty(通过 clang,经过优化):

push    rax
call    vector::size() const
test    eax, eax
sete    al
pop     rcx
ret
Run Code Online (Sandbox Code Playgroud)

为什么要分配堆栈空间?它根本没有被使用。该pushpop可以省略。MSVC 和 gcc 的优化构建也为此功能使用堆栈空间(请参阅有关Godbolt 的内容),因此必须有一个原因。

c++ code-generation abi calling-convention stack-allocation

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

模板参数中 int&amp; 相等

假设我们有以下程序:

template <class T, T n1, T n2>
struct Probe { 
    static const int which = 1;
};

template <class T, T n>
struct Probe<T, n, n> { 
    static const int which = 2;
};


int i = 123;

const int myQuestion = Probe<int&, i, i>::which;
Run Code Online (Sandbox Code Playgroud)

我很确定,这myQuestion应该2与 C++ 标准的版本无关,但编译器不同意这一点。MSVC 和 clang 表示,2C++14 之前,1C++17 以后。请参阅演示。真相是什么?

到目前为止我的调查:

  • 我在C++标准中找到了相关的一句话。它存在于C++11C++14C++17C++20中。它没有改变。
  • 如果T从示例代码中删除该参数,所有编译器都同意,myQuestion2 …

c++ template-specialization c++14 c++17 non-type-template-parameter

10
推荐指数
0
解决办法
207
查看次数

哪些类型是可简单构造的?

我知道,许多类型(例如 POD 类型)都是默认可构造的。但是除了空参数列表之外,哪些类型可以从参数列表轻松构造?例如,什么类型可以简单地从 构造出来int?我想不出任何一个。

int以下类型在 C++17 中不能轻易构造(现场演示):

#include <type_traits>

struct X { int x; };
struct Y { Y(int) {} };
struct Z { Z(int) = delete; };

static_assert(std::is_trivially_constructible<X, int>::value == false);
static_assert(std::is_trivially_constructible<Y, int>::value == false);
static_assert(std::is_trivially_constructible<Z, int>::value == false);
Run Code Online (Sandbox Code Playgroud)

c++ type-traits language-lawyer

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

ADL在constexpr函数中不起作用(仅适用于clang)

以下代码使用MSVC和gcc进行编译,但不能使用clang进行编译。为什么?

如果CallFoo ()is的话,似乎ADL无法正常工作constexpr。查看评论。

template <class T>
constexpr void CallFoo  ()          // Remove constexpr to fix clang compilation error.
{
    Foo (T ());
}


class Apple {};


int main ()
{
    CallFoo<Apple> ();
}


constexpr void Foo (Apple)
{
}
Run Code Online (Sandbox Code Playgroud)

Clang错误消息(请参阅godbolt.org):

<source>:4:5: error: use of undeclared identifier 'Foo'
    Foo (T ());
    ^
<source>:13:5: note: in instantiation of function template specialization 'CallFoo<Apple>' requested here
    CallFoo<Apple> ();
    ^
Run Code Online (Sandbox Code Playgroud)

c++ templates clang argument-dependent-lookup constexpr

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

基于参数的依赖名称查找

在cppreference.com上的描述

模板中使用的从属名称的查找被推迟到知道模板参数为止,这时ADL会检查具有外部链接的函数声明,这些声明从模板定义上下文模板实例化上下文中可见。

与此相反,以下代码片段可以使用三个编译器(MSVC,clang和gcc)很好地进行编译:

template <class T>
void CallFoo ()
{
    Foo (T ());
}


class Apple {};


int main ()
{
    CallFoo<Apple> ();
}


static void Foo (Apple)
{
}
Run Code Online (Sandbox Code Playgroud)

Foo是以下内容中的从属名称CallFoo:它取决于模板参数T。但是,Foo尽管违反了上面引用的两个规则,但是编译器仍然可以找到该函数。

  • Foo从的定义或实例中都看不到的声明CallFoo,因为它位于两者之下。
  • Foo 有内部联系。

这三个编译器都不可能有错误。我可能误会了一些东西。您能详细说明一下吗?

c++ linkage dependent-name language-lawyer argument-dependent-lookup

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

实例化变量模板时要考虑代码的哪一部分?

在以下程序中,全局变量isCompleteType<Apple>由 clang 和 gcc 以不同的方式初始化(​​位于Godbolt.org 上):

template <class T>
constexpr bool IsCompleteTypeHelper (decltype (sizeof (T))) { return true; }

template <class T>
constexpr bool IsCompleteTypeHelper (...)                   { return false; }

template <class T>
bool isCompleteType = IsCompleteTypeHelper<T> (0);


class Apple;


int main ()
{
    return isCompleteType<Apple>;
}


class Apple {};
Run Code Online (Sandbox Code Playgroud)
  • Clang 10.0.0 初始化isCompleteType<Apple>true.
  • Gcc 9.3 初始化isCompleteType<Apple>false.

由于Apple可以生成变量的定义true的实例化之后isCompleteType,因此我得出结论,编译器在初始化变量时会执行以下操作。

  • Clang 考虑整个翻译单元。
  • Gcc …

c++ language-lawyer incomplete-type variable-templates c++14

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

在 c++11 中按值捕获成员变量的好方法是什么?

struct myclass {
    myclass(){}
    myclass(int qx):z(qx){   }
    std::function<void()> create() {
        auto px = [z](){
            std::cout << z << std::endl;
        };
        return px;
    }
    int z;
};

myclass my;
my.z = 2;
auto func = my.create();
func();
my.z = 3;
func();
Run Code Online (Sandbox Code Playgroud)

这段代码将在 gcc 4.6.3 中编译,它会做正确的事情来制作成员变量的副本z,并且两个 print 都会得到2. 在 gcc 4.8.2 这不再编译..

error: 'this' was not captured for this lambda function
Run Code Online (Sandbox Code Playgroud)

我想知道为什么这个功能被删除了,因为它非常有用。

c++ g++ c++11

6
推荐指数
1
解决办法
2891
查看次数

带有运算符语法的错误消息,但不是带有函数语法的错误消息

为什么在+使用运算符语法调用一元时会收到错误消息?如果我用函数语法调用它,就可以了。现场演示

template <int size>
struct Buffer { char buf[size]; };

template <class T>
struct Wrapper { void operator+() {} };

Wrapper<Buffer<-5>> a;

void f1() { +a; }               // error: Buffer<-5>::buf has negative size
void f2() { a.operator+(); }    // OK
Run Code Online (Sandbox Code Playgroud)

c++ templates

6
推荐指数
1
解决办法
88
查看次数