标签: c++-concepts

Concepts-Lite如何与可变参数模板交互?

我观看了Bjarne Strustrup在Going Native 2013中的演讲,他给出了以下关于C++即将出现的概念特色的例子.

void sort(Container& c); // terse notation

// Expands to
template <Container __Cont>
  void sort(__Cont& c); // shorthand notation

// Expands to 
template <typename __Cont>
  requires Container<__Cont>()
    void sort(__Cont & c);
Run Code Online (Sandbox Code Playgroud)

我的问题是如何使用可变参数模板?

假设我想maximum使用Comparable概念定义可变参数函数.是否接受以下语法?

auto maximum(Comparable a)
{
     return a;
}

auto maximum(Comparable c, Comparable... rest)
{        
    return std::max(a, maximum(rest...));
}
Run Code Online (Sandbox Code Playgroud)

如果是这样Comparable...意味着参数包中的所有元素都是相同的类型,或者只是它们都是Comparable类型,以便包可以包含intstring?(两者相当,但彼此不相同)

好奇的人想知道.

c++ variadic-templates c++-concepts

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

C++概念是存在类型的一种形式吗?

我在维基百科(Existential_types)上看到存在类型的定义,它在某种程度上与C++中的概念(特别是概念精简版)相似.

C++概念是存在类型的一种形式吗?

如果没有,两者之间有什么区别?

c++ existential-type c++-concepts

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

C++概念与static_assert

c ++概念中有什么新东西?根据我的理解,它们在功能上等同于使用static_assert,但是以"漂亮"的方式意味着编译器错误将更具可读性(因为Bjarne Stroustup说你不会得到10页或错误,而只是一个).

基本上,您可以使用概念实现的一切都是真的static_assert吗?

有什么我想念的吗?

c++ static-assert c++-concepts

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

概念lite如何与通用引用相互作用?

我最近看了一下这个视频,解释了C++中概念精简版的概念,这些概念很可能在今年作为TS出现.现在,我也了解通用引用/转发引用(如描述在这里),并是t &&可以根据上下文两个方面的含义(即,如果类型推演正在执行或没有).这自然会引出概念如何与通用引用相互作用的问题?

为了使它具体化,在下面的例子中我们有

void f(int&& i) {}

int i = 0;
f(i);    // error, looks for f(int&)
f(0);    // fine, calls f(int&&)
Run Code Online (Sandbox Code Playgroud)

template <typename T>
void f(T&& test) {}

int i = 0;
f(i);    // fine, calls f(T&&) with T = int& (int& && = int&)
f(0);    // fine, calls f(T&&) with T = int&& (int&& && = int&&)
Run Code Online (Sandbox Code Playgroud)

但是如果我们使用概念会发生什么?

template <typename T>
    requires Number<T>
void f(T&& test) {}

template <Number T>
void g(T&& test) …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts universal-reference forwarding-reference c++17

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

C++ Concepts是否允许我的类在声明/定义中指定它满足某些概念?

目前我能想到的最好的方法是使用static_assert,但我更喜欢更好的方式.

#include <set>
#include <forward_list>

using namespace std;

template<typename C>
concept bool SizedContainer = requires (C c){
    c.begin();
    c.end();
    {c.size()} -> size_t;
};

static_assert(SizedContainer<std::set<int>>);
static_assert(!SizedContainer<std::forward_list<int>>);
static_assert(!SizedContainer<float>);

class MyContainer{
public:
    void begin(){};
    void end(){};
    size_t size(){return 42;}; 
};

static_assert(SizedContainer<MyContainer>);



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

c++ c++-concepts c++20

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

为什么范围的算法与std的迭代器不兼容?

#include <vector>
#include <iostream>
#include <range/v3/all.hpp>

int main()
{
    auto coll = std::vector{ 1, 2, 3 };

    ranges::copy(
        coll,
        ranges::ostream_iterator<int>{  std::cout, ", " }
    ); // ok

    ranges::copy(
        coll, 
        std::ostream_iterator<int>{ std::cout, ", " }
    ); // error 
}
Run Code Online (Sandbox Code Playgroud)

问题显示在上面的代码中.我使用range-v3-0.3.7.

对我来说,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求即可.

如果是这样,为什么范围的算法不与std的迭代器兼容?

c++ iterator c++-concepts range-v3 c++20

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

使用概念具有特定值类型的任何容器的 C++ 迭代器

我想摆脱enable_if模板中的所有邪恶s 并用 C++20 概念替换它们,但是几乎没有关于概念的任何信息,并且几乎我阅读的任何来源的语法都发生了变化。

这是一个函数,它接受任何带有MyClass值的容器的两个迭代器:

template <class IteratorType, typename = std::enable_if<std::is_same<
                                typename std::iterator_traits<IteratorType>::value_type,
                                MyClass
                            >::value, void>>
void myFunction( IteratorType begin, IteratorType end ) {}
Run Code Online (Sandbox Code Playgroud)

我知道可以使用概念转换此功能,但我找不到好的线索开始。

c++ sfinae enable-if c++-concepts c++20

11
推荐指数
3
解决办法
514
查看次数

部分特化类的成员定义

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

让我们慢慢来,从适用于所有主要编译器(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
查看次数

函数参数可以用作模板参数吗?

在下面的程序中,函数foo接收v类型为 的参数std::integral_constant<bool, true>,该参数用于传入模板参数A<b>

template <bool>
struct A{};

constexpr bool foo(auto b) {
    return requires { typename A<b>; };
}

static_assert( foo( std::true_type{} ) );
Run Code Online (Sandbox Code Playgroud)

GCC 和 MSVC 都认为它有效(foo返回true),但在 Clang 中foo返回false。在线演示: https: //gcc.godbolt.org/z/j6Mnqjvbz

这里哪个编译器是正确的?

c++ templates language-lawyer c++-concepts c++20

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

在此类的方法的 require 子句中使用类

这是一个简单的例子:

#include <type_traits>
#include <ranges>
#include <vector>

struct MyClass
{
    void f( int ) {}
    void f( char ) {}

    template <std::ranges::input_range Rng>
        requires requires ( MyClass cls, const std::ranges::range_value_t<Rng>& val )
        {
            { cls.f( val ) };
        }
    void f( Rng&& rng ) {}
};

int main()
{
    MyClass cls;
    cls.f( 10 );
    cls.f( 'a' );
    cls.f( std::vector<int>{ 10, 15 } );
}
Run Code Online (Sandbox Code Playgroud)

根据Godbolt 的说法,这个示例在 MSVC 和 GCC 上编译成功,但在 Clang 上编译失败。标准对此类要求表达式有何规定?

更新:我们可以简化示例,以便方法调用中不存在循环(Godbolt):

#include <type_traits> …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer compiler-specific c++-concepts c++20

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