#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++ 概念来要求类派生自模板化类,而模板化类的模板参数又是另一个模板化类的派生类。
例子:
template <class T>
class A{};
template <class T>
class B{};
class X{};
class Y : public A<X> {};
class Z : public B<Y> {};
Run Code Online (Sandbox Code Playgroud)
我如何办理登机手续B,这是某些人的T表格而不指定是什么?我不想添加到 的模板参数列表中,因为我不想在派生自的每个实例上更改代码(例如最后一行)。std::is_base_of<A<X>,T>XXXBBclass Z
也在programmers.stackexchange.com上:
我知道STL概念必须存在,并且将它们称为"类"或"接口"是愚蠢的,而实际上它们只是文档化(人类)概念,当时无法转换为C++代码,但是当有机会扩展语言来容纳概念时,他们为什么不简单地修改类和/或引入接口的功能?
是不是一个非常类似于接口的概念(100%抽象类没有数据)?通过观察它,在我看来接口只是缺乏对公理的支持,但也许公理可以引入C++的接口(考虑假设采用C++中的接口来接管概念),不是吗?我认为甚至可以轻松地将自动概念添加到这样的C++接口(自动界面LessThanComparable,任何人?).
Concept_map 与Adapter模式非常相似吗?如果所有方法都是内联的,那么适配器在编译时间之外基本上不存在; 编译器只是用内联版本替换对接口的调用,在运行时直接调用目标对象.
我听说过一种称为静态面向对象编程的东西,它实质上意味着在泛型编程中有效地重用面向对象的概念,从而允许使用大多数OOP的功能而不会产生执行开销.为什么不进一步考虑这个想法?
我希望这很清楚.如果你认为我不是,我可以改写这个; 请告诉我
在范围符合规范N4622的Same概念被定义为采取两种类型T和U,但有时用作内requires只有一个这样的:
{ t } -> Same<T>;
Run Code Online (Sandbox Code Playgroud)
能够扣除第二种类型的规则是什么U?(例如来自Concepts spec N4630)
最简单的类似例子是:
template <class T, class U>
concept bool C = (sizeof(T) == sizeof(U)) && (sizeof(U) != 1);
template <class T>
concept bool D = requires(T t){
// How is U deduced here?
{t} -> C<T>;
};
template <class T>
requires D<T>
void fn() {}
int main() {
// Fails with: unable to deduce placeholder type 'C<char>' from 't' …Run Code Online (Sandbox Code Playgroud) 如cppreference中所述,类型T为CopyConstructible的要求是它也是MoveConstructible.
STL CopyConstructible概念的草案包含:
Run Code Online (Sandbox Code Playgroud)template <class T> concept CopyConstructible = std::MoveConstructible<T> && std::Constructible<T, T&> && std::ConvertibleTo<T&, T> && std::Constructible<T, const T&> && std::ConvertibleTo<const T&, T> && std::Constructible<T, const T> && std::ConvertibleTo<const T, T>;
它支持命名的需求声明.鉴于上述定义,类似于:
struct HaveCopy {
HaveCopy(const HaveCopy&) = default;
HaveCopy(HaveCopy&&) = delete;
HaveCopy& operator= (const HaveCopy&) = default;
HaveCopy& operator= (HaveCopy&&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
没有简单的测试:
static_assert(std::CopyConstructible<HaveCopy>);
Run Code Online (Sandbox Code Playgroud)
而它通过了旧的:
static_assert(std::is_copy_constructible<HaveCopy>::value);
Run Code Online (Sandbox Code Playgroud)
那么,问题是为什么呢?标准委员会对此事的意图是什么?HaveCopy不是可构造的,但在我看来几乎是可复制的,并且std::is_copy_constructible<>与我一致.
Copyable概念也继承了相同的行为,即:
Run Code Online (Sandbox Code Playgroud)template <class T> concept Copyable …
在下面的示例中,函数自变量用于测试require表达式是否充分利用了它们。require表达式不带参数;它直接使用函数作用域中的变量:
#include <cstddef>
#include <vector>
template<typename T>
void Resize(T &v, std::size_t const n)
{
if constexpr (requires { v.resize(n); })
v.resize(n);
}
template<typename T>
void Eziser(T &v, std::size_t const n)
{
if constexpr (requires { v.eziser(n); })
v.eziser(n);
}
int main()
{
std::vector<int> v;
Resize(v, 10u);
Eziser(v, 10u);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码使用Clang概念分支进行编译。但是,GCC10仅接受对的呼叫Resize。GCC9 ICE。Clang正确接受吗?
我正在学习概念,我想不出一种方法来限制非类型模板参数的值(不是类型)。
编译的代码示例,尽管我希望它没有(由于需求失败):
#include <cassert>
enum Bla{
Lol,
Haha
};
template<Bla b>
requires requires{
// my guess is that this just checks that this is valid expression, not
// that it is true
b>1;
}
void f(){
assert(b>1);
}
int main() {
f<Lol>(); // compiles, not funny ;)
}
Run Code Online (Sandbox Code Playgroud)
注意:这是一个简化的例子(我想要“模板重载”)所以static_assert对我不利,我试图避免,std::enable_if因为语法是可怕的。
我已经知道这个概念是一个编译时谓词,它可以约束模板或auto.
我发现这些概念将返回 type 的纯右值bool,所以我可以打印它来测试自己。
我还阅读了这个特定问题Can概念(C++ 20)可以用作布尔值吗?以及澄清可用作布尔值的概念的答案。
[temp.names] (8) 一个concept-id 是一个simple-template-id,其中template-name 是一个concept-name。概念 ID 是 bool 类型的纯右值,并且不命名模板特化。如果指定的模板参数满足概念的规范化约束表达式 ([temp.constr.constr]),则概念 ID 评估为真,否则为假。
例如:
template <typename T>
concept meowable = requires (T obj) {
{ obj.meow() } -> std::same_as<T&>;
};
struct Dog {};
struct Cat { Cat& meow(); };
struct Wolf { Wolf& woof(); };
Run Code Online (Sandbox Code Playgroud)
应用:
std::cout << std::boolalpha;
std::cout << "Has meow?" << '\n'
<< "Dog: " << meowable<Dog> << '\n'
<< "Cat: " << meowable<Cat> << '\n' …Run Code Online (Sandbox Code Playgroud) c++ type-traits template-meta-programming c++-concepts c++20
member我希望使内部的存在dat依赖于B(或其他一些概念)。
template <bool B>
struct dat {
void member_func() requires (B) {} //ok
std::byte member requires (B); //err
};
Run Code Online (Sandbox Code Playgroud)
我知道这可能与专业化有关,但据我所知,如果需要多个不同的成员要求,那会变得非常难看。
如果没有专门化,这种行为是否可能?
c++ ×10
c++-concepts ×10
c++20 ×7
iterator ×1
non-type-template-parameter ×1
oop ×1
range-v3 ×1
templates ×1
type-traits ×1