据我了解,自定义分配器必须符合分配器概念的要求。但是,基于该界面,我看不出当向量耗尽储备时我将如何选择新的分配量。
例如,我机器上的当前实现每次reserve在push_back(). 我想提供一个速度慢且内存敏感的自定义分配器。它只会分配前一个capacity+1来容纳新元素。
这些是我正在研究的概念的接口:
a.allocate(n)
a.allocate(n, cvptr) (optional)
Run Code Online (Sandbox Code Playgroud)
我制作了一个工作样板分配器,如下所示:
#include <limits>
#include <iostream>
template <class T> class MyAlloc {
public:
// type definitions
typedef T value_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T &reference;
typedef const T &const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
pointer address(reference value) const {
return &value;
}
const_pointer address(const_reference value) const {
return &value;
}
size_type max_size() const throw() {
return std::numeric_limits<std::size_t>::max() / sizeof(T);
} …Run Code Online (Sandbox Code Playgroud) 我有以下使用概念的代码:
struct bar {
void foo() {}
};
template <typename T>
concept Fooable = requires (const T& t) { // const bar& t doesn't support t.foo()
{ t.foo() };
};
template <typename Fooable>
void callfoo(Fooable bar)
{
bar.foo();
}
int main()
{
bar b;
callfoo(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望代码不会编译,因为bar不支持调用foo()const 实例。但是它确实编译精细链接。
cppreference 上的参数列表描述在这方面没有太大帮助:
参数列表 - 一个逗号分隔的参数列表,就像在函数声明中一样,除了不允许使用默认参数并且它不能以省略号结尾(除了表示包扩展的省略号)。这些参数没有存储、链接或生命周期,仅用于帮助指定需求。这些参数在需求序列的结束 } 之前都在范围内。
我是否误解了 cv 限定符在 requires 表达式参数列表中的用途?我完全错过了什么吗?我对 cppreference 有一些使用通用参考参数的示例感到更加困惑,因此其中必须有一些要点。
我正在使用gcc9with -fconcepts(尽管 gcc trunk 和 clang 与 …
下面的代码摘自cppref:
#include <string>
using namespace std::literals;
template<typename T>
concept bool EqualityComparable = requires(T a, T b)
{
{
a == b
}
->bool;
};
void f(EqualityComparable&&) {}
int main()
{
f("abc"s);
}
Run Code Online (Sandbox Code Playgroud)
然而,它不能用 clang-10 编译:
[root@mine ~]# clang++ -std=c++20 -stdlib=libc++ main.cpp
main.cpp:6:14: warning: ISO C++20 does not permit the 'bool' keyword after 'concept' [-Wconcepts-ts-compat]
concept bool EqualityComparable = requires(T a, T b)
~~~~~^
main.cpp:11:7: error: expected concept name with optional arguments
->bool;
^
main.cpp:14:8: error: unknown type name …Run Code Online (Sandbox Code Playgroud) 在 C++ 中,需要提及指针的类型。例如,
int a = 5;
int * p = &a;
Run Code Online (Sandbox Code Playgroud)
这里,'int *' 中的'int' 是必要的。我发现的原因是它需要取消引用。(知道要读取的字节数及其解释)和指针算术。
但是,如果我写:-
int a = 5;
char * p = &a;
float * p2 = &a;
//etc
Run Code Online (Sandbox Code Playgroud)
显示错误,说明无法将 char*、float* 等指针分配给 int 变量。好的..,所以编译器知道我想要指针的变量类型。这与普通变量不同,在普通变量中,编译器并不确切知道我想要哪种类型。例如:-
int a = 5;
float b = 5;
double c = 5;
long d = 5;
char e = 5;
Run Code Online (Sandbox Code Playgroud)
所有这些都很好。我需要在这里写类型,因为编译器不知道我想要哪种类型,因为所有这些都可以工作。
但是,在指针的情况下,它知道我要为其声明指针的变量的确切类型。
即使我使用显式类型转换,我仍然会以某种方式告诉我需要的指针类型,并且仍然必须指定正确的指针类型。
int a = 5;
char * b = (char*)&a;//This would work.
//However this,
int …Run Code Online (Sandbox Code Playgroud) 我正在使用 g++ 10 学习 C++20 标准的新实现概念。我坚持一个简单的类型要求。即我想实现模板参数T具有T::inner成员名称的要求。这是我的错误代码。这个简单的代码有什么问题以及如何修复它?
#include<concepts>
template<typename T>
concept ContainsInner = requires
{
typename T::inner;
};
template<ContainsInner T>
struct S{};
struct Q
{
int inner;
};
int main()
{
S<Q> s; // instantiate S with Q for template type,
// which must satisfy the ContainsInner concept.
// Q indeed contains the inner name but still the compilation fails
}
Run Code Online (Sandbox Code Playgroud) 我不明白为什么std::invocable在以下代码中lambda 和函数都没有被识别为兼容类型:
#include <concepts>
#include <iostream>
void f( std::invocable auto callback)
{
callback(47);
}
void function_callback(int i)
{
std::cout << i << std::endl;
}
auto lambda_callback = [](int i )
{
std::cout << i << std::endl;
};
int main(int)
{
f(&function_callback);
f(lambda_callback);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用-std=c++2a启用了标志的GCC 主干。
Forward_iterator 编译正常!
#include <concepts>
#include <iterator>
// #include <iterator_concept>
using namespace std;
template<typename T>
// struct my_iterator : std::forward_iterator_tag{
struct my_iterator : std::bidirectional_iterator_tag {
T& operator*()const{
return *pointer;
}
my_iterator& operator++(){
++pointer;
return *this;
}
my_iterator operator++(int){
auto copy = *this;
++pointer;
return copy;
}
// my_iterator& operator--(){
// --pointer;
// return *this;
// }
// my_iterator operator--(int){
// auto copy = *this;
// --pointer;
// return copy;
// }
using difference_type = ptrdiff_t;
using value_type = T;
// auto …Run Code Online (Sandbox Code Playgroud) 在下面的代码片段中,我使用了可变参数模板 findSum 函数,并确保该函数的参数类型使用概念相同,但有人可以建议我如何确保该函数的返回类型也与参数类型匹配。
#include <iostream>
#include <concepts>
template<typename F,typename... R>
struct FirstVariadicType
{
using Type = F;
};
template<typename... Ts>
requires requires(Ts... args){
std::conjunction_v<std::is_same<typename FirstVariadicType<Ts...>::Type, Ts>...>;
}
auto findSum(Ts... args)
{
return (... + args);
}
int main()
{
std::cout<<"sum of 2 and 3 is "<<findSum(2,3)<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) C++ 容器不包含 const 元素,例如您有const std::vector<int>,而不是std::vector<const int>。当我尝试根据传递的容器是否为常量来调整函数的返回值类型时,这有点不幸。
这是一个激励性的例子,请不要过多关注算法或boost的使用,我只使用它,因为C++ optional 不支持引用。
这段代码似乎可以工作,但代码看起来很丑,所以我想知道概念是否给我们提供了一种以更好的方式编写它的方法。我认为不是,因为基本上概念只是谓词,但我希望有一些好的东西,特别是返回类型非常垃圾。
template<typename C>
using match_const = std::conditional_t< std::is_const_v<std::remove_reference_t<C>>,
const typename std::remove_reference_t<C>::value_type,
typename std::remove_reference_t<C>::value_type>;
// no constraints
auto ofind(auto& container, const auto& value) -> boost::optional<match_const<decltype(container)>&> {
if (auto it = std::ranges::find(container, value); it!=container.end()){
return *it;
}
return boost::none;
}
// dummy concept
template<typename C>
concept Container = requires (C c){
{c.begin()};
{c.end()};
{c.size()} -> std::same_as<size_t>;
};
// constraints version
auto ofind2(Container auto& container, const auto& value) …Run Code Online (Sandbox Code Playgroud)