标签: c++17

用任意可调用的折叠表达式?

回顾关于折叠的C++ 17 论文(以及cppreference),我很困惑为什么选择只与运营商合作?乍一看似乎(... + args)只是通过+在元素之间推一个标记来扩展它更容易args,但我不相信这是一个伟大的决定.

为什么二元lambda表达式不能同样工作并遵循与上面相同的扩展?对我来说,在不支持任意可调用语言的情况下将折叠语法添加到语言中是很不可思议的,语法是否允许使用我只是没有看到的方法?


更新:这适用于min()具有clang 的可变函数

template <typename T>
struct MinWrapper {
    const T& obj;
};

template <typename T, typename U, typename V=std::common_type_t<T,U>>
constexpr MinWrapper<V> operator%(
        const MinWrapper<T>& lhs, const MinWrapper<U>& rhs) {
    return {lhs.obj < rhs.obj ? lhs.obj : rhs.obj};
}


template <typename... Ts>
constexpr auto min(Ts&&... args) {
    return (MinWrapper<Ts>{args} % ...).obj;
}
Run Code Online (Sandbox Code Playgroud)

c++ fold c++17

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

如何在C++中模拟解构?

在JavaScript ES6中,有一种称为解构的语言功能.它也存在于许多其他语言中.

在JavaScript ES6中,它看起来像这样:

var animal = {
    species: 'dog',
    weight: 23,
    sound: 'woof'
}

//Destructuring
var {species, sound} = animal

//The dog says woof!
console.log('The ' + species + ' says ' + sound + '!')
Run Code Online (Sandbox Code Playgroud)

我可以在C++中做些什么来获得类似的语法并模拟这种功能?

javascript c++ language-construct destructuring c++17

35
推荐指数
3
解决办法
5548
查看次数

std :: is_invocable为false但std :: invoke有效

以下程序的输出似乎自相矛盾:

#include <type_traits>
#include <iostream>
#include <functional>

void foo(int&){ std::cout << "called\n"; }

int main() {
    int a;
    foo(a);
    std::cout << std::is_invocable_v<decltype(foo), decltype(a)> << std::endl;
    std::invoke(foo, a);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

called
0
called
Run Code Online (Sandbox Code Playgroud)

在我看来,调用一个不可调用的函数?这里发生了什么?

c++ c++17

35
推荐指数
1
解决办法
2793
查看次数

为什么remove_reference在函数上不起作用?

前几天进行一些模板元编程时遇到了奇怪的事情。基本上可以归结为这个断言没有(正如我期望的那样)通过。

static_assert(std::is_same_v<void(), std::remove_reference_t<void()&>>);
Run Code Online (Sandbox Code Playgroud)

起初我以为我在定义函数引用时犯了语法错误,但是这个断言通过了,表明事实并非如此。

static_assert(std::is_same_v<void()&, void()&>);
Run Code Online (Sandbox Code Playgroud)

我还尝试实现remove_reference自己从cppreference复制源,但这也不起作用。这里发生了什么?

c++ templates types c++17

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

使用透明的std函数对象时,我们还需要编写空的尖括号吗?

使用类模板参数推导我们可以写:

std::less Fn;
Run Code Online (Sandbox Code Playgroud)

但是,G ++ 8.2拒绝此代码:

#include <algorithm>
#include <vector>
#include <functional>

int main()
{
std::vector v= { 1, 3, 2, 7, 5, 4 };

std::sort(v.begin(),v.end(),std::greater());
}
Run Code Online (Sandbox Code Playgroud)

发出以下错误:

error: cannot deduce template arguments for 'greater' from ()
Run Code Online (Sandbox Code Playgroud)

Clang ++ 7.0和MSVC 15.8.0在没有警告的情况下编译它.哪个编译器是对的?

c++ templates language-lawyer argument-deduction c++17

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

CppCon 2018,Nicolai Josuttis:为什么这些被解释为迭代器?

Nicolai Josuttis在CppCon 2018上的"C++初始化的梦魇"演讲中,曾经有过以下代码:

std::vector< std::string > v07 = {{ "1", "2" }};
Run Code Online (Sandbox Code Playgroud)

Nicolai 说以下(转录矿):

问题是,这里发生的是,我们将这两个参数解释为迭代器.所以这些是迭代器,所以是范围的开始,是范围的结束,它们应该引用相同的字符范围; 因为字符隐式转换为字符串,这将编译.如果你很幸运,你会得到一个coredump.如果没有,你就有了一个大问题.

他在那里失去了我.有人可以一步一步地解释这里发生了什么吗?

c++ initialization c++17

34
推荐指数
1
解决办法
1124
查看次数

为什么从构造函数参数中删除“const”会阻止类被实例化?

从第 12 行删除const可以防止该类What在编译期间被实例化。What无论声明中的常量如何,我都不希望被实例化。这在 clang、gcc 和 MSVC 之间是一致的,所以我认为它是标准的。标记构造函数explicit也不会阻止实例化。我在这里不明白什么?为什么常量会产生影响?

template <typename T> constexpr bool just_false() { return false; }

template<typename T>
class What {
    static_assert(just_false<T>(), "Why was this class instantiated?");
};

struct The {};

struct Heck {
    Heck(The) {}
    Heck(const What<int>&); // Removing 'const' from this line stops 'What<int>' from being instantiated
};

int main() {
    The the;
    Heck{the};
}
Run Code Online (Sandbox Code Playgroud)

just_false咒语只是为了防止静态断言始终触发,无论实例化如何。

编译器浏览器链接:https ://godbolt.org/z/8cETcfss5

c++ constructor c++17

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

Lambda隐式捕获因结构化绑定声明的变量而失败

使用以下代码,我得到一个编译错误C2065 'a': undeclared identifier(使用Visual Studio 2017):

[] {
    auto [a, b] = [] {return std::make_tuple(1, 2); }();
    auto r = [&] {return a; }(); //error C2065
}();
Run Code Online (Sandbox Code Playgroud)

但是,以下代码编译:

[] {
    int a, b;
    std::tie(a, b) = [] {return std::make_tuple(1, 2); }();
    auto r = [&] {return a; }();
}();
Run Code Online (Sandbox Code Playgroud)

我以为这两个样本是等价的.它是编译器错误还是我错过了什么?

c++ lambda c++17 structured-bindings visual-studio-2017

33
推荐指数
4
解决办法
2931
查看次数

为什么std :: any_cast不支持隐式转换?

当从实际存储类型到请求类型的隐式转换可能时,为什么std::any_cast抛出std::bad_any_cast异常?

例如:

std::any a = 10;  // holds an int now
auto b = std::any_cast<long>(a);   // throws bad_any_cast exception
Run Code Online (Sandbox Code Playgroud)

为什么这是不允许的,是否有允许隐式转换的解决方法(如果std::any保存的确切类型未知)?

c++ c++17

33
推荐指数
3
解决办法
3472
查看次数

在C++中混淆模板17 std :: visit的例子

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++ lambda variadic-templates generic-lambda c++17

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