std::visit()在cppreference中查看页面时,https: //en.cppreference.com/w/cpp/utility/variant/visit,
我遇到了我无法理解的代码......
这是缩写版本:
#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;
int main() {
std::vector<std::variant<int,long,double,std::string>> vec = { 10, 15l, 1.5, "hello" };
for (auto& v : vec) {
std::visit(overloaded{
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << …Run Code Online (Sandbox Code Playgroud) C++标准化委员会中有一个研究小组,在C++ 1z或之后提供编译时反射.我想知道预期工具的目的是什么以及功能有多强大?
例如,是否可以使用这些工具命名函数或类?
struct A {int f() {return 42;}};
struct B {int (std::reflect<A>::member<0>::declname)() {return 43;}};
// equivalent to struct B {int f() {return 43;}};
Run Code Online (Sandbox Code Playgroud)
如果它没有这个那么强大,那么典型的用例是什么?
更新: 条件显式使其成为C++ 20草案.更多关于cppreference
该cppreference的std ::元组构造页面有一堆的C++ 17的笔记说这样的话:
这个构造函数是
explicitif和only ifstd::is_convertible<const Ti&, Ti>::value至少为falsei
如何编写有条件显式的构造函数?想到的第一种可能性是,explicit(true)但这不是合法的语法.
尝试enable_if失败:
// constructor is explicit if T is not integral
struct S {
template <typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
S(T) {}
template <typename T,
typename = typename std::enable_if<!std::is_integral<T>::value>::type>
explicit S(T) {}
};
Run Code Online (Sandbox Code Playgroud)
有错误:
error: ‘template<class T, class> S::S(T)’ cannot be overloaded
explicit S(T t) {}
Run Code Online (Sandbox Code Playgroud) 从bug 80985开始考虑这个例子:
template <class Func>
void call(Func f)
{
f();
}
void func() noexcept { }
int main()
{
call(func);
}
Run Code Online (Sandbox Code Playgroud)
正如您所做的那样,在启用所有警告的情况下进行编译会产生:
$ g++ -std=c++14 -Wall foo.cxx
foo.cxx:2:6: warning: mangled name for ‘void call(Func) [with Func = void (*)() noexcept]’ will change in C++17 because the exception specification is part of a function type [-Wnoexcept-type]
void call(Func f)
^~~~
Run Code Online (Sandbox Code Playgroud)
我应该怎么做这个警告呢?修复是什么?
在下面的示例中,我可以从lambda内部访问constexpr变量x,y而无需显式捕获它.如果x未声明为,则无法执行此操作constexpr.
是否有适用constexpr于捕获的特殊规则?
int foo(auto l) {
// OK
constexpr auto x = l();
auto y = []{return x;};
return y();
// NOK
// auto x2 = l();
// auto y2 = []{ return x2; };
// return y2();
}
auto l2 = []{return 3;};
int main() {
foo(l2);
}
Run Code Online (Sandbox Code Playgroud) 在C++ 17,std::map并std::unordered_map有一个新的成员函数模板:try_emplace().在n4279中提出的这一新增功能表现相似emplace(),但具有以下优点:
try_emplace()如果插入没有发生,则不会从rvalue参数移动.这在操作其值为仅移动类型的地图时非常有用,例如std::unique_ptr.try_emplace()分别处理密钥和参数mapped_type,这使得它比以value_type(即std::pair)表示的通用变更器更直观.鉴于上述优点,在编写仅使用C++ 1z的代码时,您是否会使用emplace()C++ 11而不是try_emplace()C++ 1z?
参考这个问题.用于初始化constexpr变量的核心常量表达式是错误的y.这么多是给定的.
但如果我试着if变成if constexpr:
template <typename T>
void foo() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1 << x;
}
}
int main(){
foo<int>();
}
Run Code Online (Sandbox Code Playgroud)
错误仍然存在.GCC 7.2仍然给出:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
但我认为语义检查应该在废弃的分支上保持不成形.
constexpr但是,通过lambda 进行间接确实有帮助:
template <typename T>
void foo(){
constexpr int x = -1;
constexpr auto p = []() constexpr { return x; }; …Run Code Online (Sandbox Code Playgroud) 例如,
#include <iostream>
int main() {
unsigned n{};
std::cin >> n;
std::cout << n << ' ' << (bool)std::cin << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输入时-1,clang 6.0.0输出,0 0而gcc 7.2.0输出4294967295 1.我想知道谁是对的.或者两者都是正确的标准没有指定这个?如果失败,我认为(bool)std::cin被评估为假.clang 6.0.0也输入失败-0.
这个定义有效:
const auto &b{nullptr};
Run Code Online (Sandbox Code Playgroud)
虽然失败了:
auto *b{nullptr};
Run Code Online (Sandbox Code Playgroud)
我试图在Visual C++,GCC和Clang中编译它.他们都抱怨"不能推断出类型".
在第二种情况下,不b应该推断出有某种类型的std::nullptr_t?
Consider
struct A1 {
constexpr A1& operator=(const A1&) = default;
~A1() {}
};
struct A2 {
constexpr A2& operator=(const A2&) = default;
~A2() = default;
};
struct A3 {
~A3() = default;
constexpr A3& operator=(const A3&) = default;
};
Run Code Online (Sandbox Code Playgroud)
GCC and MSVC accept all three structs. Clang rejects A1 and A2 (but accepts A3), with the following error message:
Run Code Online (Sandbox Code Playgroud)<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A1& operator=(const A1&) = default; ^ <source>:6:5: error: …