当我发现可以将用户定义的文字模板化时,我感到很惊讶:
template <char ...C> std::string operator ""_s()
{
char arr[]{C...};
return arr;
}
// ...
std::cout << 123_s;
Run Code Online (Sandbox Code Playgroud)
但以上声明不适用于字符串文字:
"123"_s
Run Code Online (Sandbox Code Playgroud)
给我以下错误:
prog.cpp:在函数'int main()'中:
prog.cpp:12:15:错误:没有匹配的函数可调用'operator“” _ s()'
std :: cout <<“ 123” _s;prog.cpp:4:34:注意:候选:模板std :: string运算
符“” _s()模板std :: string运算符“” _s()prog.cpp:4:34:注意:模板参数推导/替换失败:
有没有办法将模板化的用户定义文字与字符串文字一起使用?
Banned.h多年来一直被吹捧为C ++的SDL工具,可以从Microsoft下载该软件,下载项目为24817。看起来Microsoft已删除了该文件。来自在线资源的以下链接反复出现在Microsoft下载中心,并显示404 。Banned.h的命运是什么?是否已被其他东西取代?
假设我们有一个#define FOO(x,y) something.
我想构造这样的宏#define BAR来BAR(x)(y)调用FOO(x,y). 如果可能的话,我该怎么做?
我尝试了以下操作:
#define BAR(x) FOO(x, BAR_
#define BAR_(y) y)
Run Code Online (Sandbox Code Playgroud)
但得到:
Run Code Online (Sandbox Code Playgroud)error: unterminated argument list invoking macro "FOO"
这是一个 MCVE:
#include <iostream>
#define FOO(x,y) std::cout << x << y << '\n';
#define BAR(x) FOO(x, BAR0
#define BAR0(y) y)
#define STR(...) STR0(__VA_ARGS__)
#define STR0(...) #__VA_ARGS__
int main()
{
std::cout << STR( BAR(1)(2) );
}
Run Code Online (Sandbox Code Playgroud)
另一种尝试:
#define BAR FOO BAR0
#define BAR0(x) (x, BAR1
#define BAR1(y) y)
Run Code Online (Sandbox Code Playgroud)
这个可以编译,但FOO (1, …
I'm trying to find a "View the Call Hierarchy" feature in Visual Studio/VSCodium.
我想做的是右键单击方法的名称(或按键盘快捷键),然后将打开一个新窗格,其中显示了所有调用被单击方法的方法以及该方法的调用树。
我在Eclipse和PyCharm中发现了这一点,但在VSCode中只发现了“查找所有引用”。
编辑:我想在Python中做到这一点,但是如果所有语言都存在这样的功能,那就太好了。
我发现clang 8.x不会忽略gcc和msvc没问题的模板化类对象的副本的情况。在我的实际应用程序中,这种多余的副本非常昂贵,因此我试图深入了解它,并最终更好地了解了何时在C ++ 17中执行复制省略。
该问题显示在下面的代码片段中。以自动返回类型声明的,返回命名类对象的函数在其主体中具有一个额外的副本构造。如果将返回值重新编码为返回未命名的临时值,则会发生省略。如果对函数进行了编码以显式返回该类的实例(而不是auto),则会发生省略。
如果结构A没有模板参数,那么还将生成完全省略的代码。
该问题表明是否所有内容都不例外或允许内联(NOINLINE可以使您无需执行代码即可在Godbolt中查看问题)。
// compiled with -O2 -std=c++17
#if defined(_MSC_VER) && !defined(__clang__)
#define NOINLINE __declspec(noinline)
#else
#define NOINLINE __attribute__((noinline))
#endif
template<int P>
struct A {
int data = 0;
NOINLINE explicit A(int data_) noexcept : data(data_) { }
NOINLINE ~A() noexcept { }
NOINLINE A(const A& other) noexcept : data(other.data) { }
};
template <int P>
NOINLINE auto return_auto_A_nrvo(const A<P>& a) noexcept {
/* clang 6.0 thru 8.0 doesn't elide copy of 'result':
gcc and msvc …Run Code Online (Sandbox Code Playgroud) 我快速阅读了有关新 chrono 类的 C++ 参考资料,但发现它们有点复杂。
那么,问题是,如何用C++20重写这段代码,来获取年、月、日、时、分、秒?
有什么变化吗?我问这个问题是因为std::localtime:它是线程不安全的。tm将在下次调用后被销毁std::localtime。
std::time_t t = std::time(nullptr);
std::tm *tm = std::localtime(&t);
int year = tm->tm_year + 1900;
int month = tm->tm_mon + 1;
int day = tm->tm_mday;
int hour = tm->tm_hour;
int minute = tm->tm_min;
int second = tm->tm_sec;
Run Code Online (Sandbox Code Playgroud) 考虑这个代码:
#include <iostream>
#include <type_traits>
struct A
{
A(int x) {std::cout << "A(" << x << ")\n";}
};
struct B : A
{
using A::A;
B(int x, int y) : A(x) {std::cout << "B(" << x << "," << y << ")\n";}
};
struct C : B
{
using B::A; // <--
// C() : B(0,0) {}
};
int main()
{
C c(1);
}
Run Code Online (Sandbox Code Playgroud)
它在 GCC 上编译并打印A(1),这意味着在B没有调用构造函数的情况下“构造”了一个实例。如果取消注释C(),则C c(1);不再编译(GCC 找不到合适的构造函数)
Clang 没有说任何关于 …
我可以使用以下模板检查来检测成员:
template <typename T, typename = void>
struct hasMember : std::false_type {};
template <typename T>
struct hasMember<T, decltype((void)T::member, void())> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)
例如:
class Test{
public:
int member;
using sometype = size_t;
}
Run Code Online (Sandbox Code Playgroud)
我可以做:
if constexpr(hasMember<Test>)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
现在假设我需要一个constexpr if告诉我一个类是否有 using 定义的函数。即可以检测到某个类(例如test)具有某种类型的 using 定义。即类似的东西
if constexpr(hasSomeType<Test>)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
这在 c++17 中可能吗?如何?
我很抱歉这个晦涩的标题,不知道如何更好地表达它。
考虑以下继承层次结构:
struct A
{
A(int) {}
};
struct B : virtual A
{
B() : A(42) {}
};
struct C : B
{
C() : A(43) {}
};
Run Code Online (Sandbox Code Playgroud)
它确实有效。现在假设我想创建一个可以在层次结构中间透明注入的模板,如下所示:
template <typename ...P>
struct Proxy : P...
{
// This constructor doesn't change anything. It was added
// to indicate that `Proxy` should only be used as a base.
protected:
Proxy() = default;
};
struct D : Proxy<B>
{
D() : A(44) {}
};
Run Code Online (Sandbox Code Playgroud)
这给了我:error: call to implicitly-deleted default …
这个答案指出了一些有趣的事情:
天真的实现比给定容器中已存在的类型的对象std::unordered_set<T>::emplace()要慢,因为可以检测到并立即退出,但天真的会首先分配一个节点,构造元素,然后检查唯一性,如果存在则销毁并释放它已经存在。insert()Tinsert()emplace()
emplace当给定参数时肯定是这种情况!= 1,因为如果不调用构造函数就无法理解它们。但也许可以优化 1 个参数的情况。
std::set<T>::emplace()想必所有这些也适用。那么,两个问题:
标准是否允许emplace()在这种情况下不构造对象?即,如果只传递一个参数,并且remove_cvref_t<argument-type>与元素类型匹配,是否可以直接emplace()应用==// <hash 参数,而无需构造新对象?
emplace与元素类型可比较,是否可以直接比较,而不构造完整元素?现代的实现实际上在实践中进行了这种优化吗?