例如,我可以定义一个概念
template <class Iter>
concept bool Iterator =
requires(Iter i, typename std::iterator_traits<Iter>::value_type val,
typename std::iterator_traits<Iter>::reference ref) {
++i;
// other implementation
};
Run Code Online (Sandbox Code Playgroud)
与海湾合作委员会6这段代码编译,而是要像Iterator<int>也将导致对true即使val和ref会替换故障.这是它的假设吗?
考虑以下代码:
#include <type_traits>
#include <iostream>
template <class T> concept bool C1 = std::is_same<T, int>::value;
template <class T> concept bool C2 =
C1<decltype(std::declval<T>() + std::declval<T>())>;
struct A {};
int main() {
std::cout << C2<int>;
std::cout << C2<A>;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC编译得很好并打印10.
但§14.10.1.2谓词约束[temp.constr.pred]的N4553说
谓词约束是一个约束,用于计算常量表达式E(5.19).
然后
替换后,E应具有bool类型.
由于C1<decltype(std::declval<A>() + std::declval<A>())>替换失败,而不是类型bool,这是否意味着该程序应该是格式错误的?
我有两个(或更多)模板,每个模板都可以调整一组特定的类,这些类由一个概念标识.为了使两个模板具有相同的名称,它们必须是特化.
template< typename T >
struct pin_in { static_assert( always_false<T>::value, . . . ); };
template< is_pin_in T >
struct pin_in< T > . . .
template< is_pin_in_out T >
struct pin_in< T > . . .
Run Code Online (Sandbox Code Playgroud)
当其中一个专业化匹配时,这可以正常工作.如果没有匹配,则选择基本模板,并且我得到断言失败.该机制有效.我喜欢概念!
但我收到的错误消息(GCC 7.2.0)指向断言.我可以以某种方式使基本模板不被选中,所以我会得到一条错误消息,告诉没有模板匹配参数类?
我想知道 C++(尤其是 C++20)中是否有一种方法可以为类/结构编写某种接口。
例如,在 Java 中,接口是一个完全“抽象类”,用于将相关方法与空主体分组:
interface Animal
{
public void animalSound();
public void run();
}
Run Code Online (Sandbox Code Playgroud)
在 C++ 中,您可以使用纯虚方法声明来实现相同的行为。
class Animal
{
public:
virtual void animalSound() = 0;
virtual void run() = 0;
};
Run Code Online (Sandbox Code Playgroud)
但是使用虚拟方法会产生运行时成本,而且我对继承不感兴趣。所以这个运行时成本应该是没有必要的。我只想检查我的“动物”类/结构的编译时间。
通过 C++20 的概念,我确信构建一个可以应用于类的构造以保证提供一组特定的方法是可以实现的。
我想做的事情看起来有点像这样。
template<typename Animal_> concept Animal =
requires()
{
(Animal_{}); // default constructable
(Animal_{}.animalSound());
(Animal_{}.run());
};
Run Code Online (Sandbox Code Playgroud)
但我不确定这样做是否非常c++。
(请问有没有办法要求方法的返回类型是特定类型?)
我不确定如何将其附加到类/结构中。
static_assert我的第一个想法是在类/结构内部使用 a :
class Cow
{
private: // compile time type checking
static_assert(std::is_matching_concept<Animal, Cow>);
public:
void animalSound() const noexcept {}
void run() const …Run Code Online (Sandbox Code Playgroud) 让我们考虑以下代码:
\n\n#include <concepts>\n\ntemplate<typename X>\nstruct Concrete_M {\n X f() const { return X{}; }\n};\n\nstruct Concrete_X {};\n\ntemplate<typename T, typename X>\nconcept M = requires (T t)\n {\n { t.f() } -> std::convertible_to<X>;\n };\n\ntemplate<M<Concrete_X>>\nstruct C {};\n\nconst C<Concrete_M<Concrete_X>> c{};\nRun Code Online (Sandbox Code Playgroud)\n\n我可以使用以下模板模板参数吗T?
template<template<typename> typename T, typename X>\nconcept M = requires (T<X> t)\n {\n { t.f() } -> std::convertible_to<X>;\n };\nRun Code Online (Sandbox Code Playgroud)\n\n我该如何改变
\n\ntemplate<M<Concrete_X>>\nstruct C {};\n\nconst C<Concrete_M<Concrete_X>> c{};\nRun Code Online (Sandbox Code Playgroud)\n\n正确使用更新概念M?我正在寻找这样的东西:
template<typename X, /* ... */>\nstruct C {};\n\nconst C<Concrete_X, /* ... …Run Code Online (Sandbox Code Playgroud) 为什么新std::sentinel_for概念要求哨兵类型是default_initializable(via semiregular)?这是否排除了一大类有用的哨兵类型,其中默认构造没有任何意义?
例子:
//Iterate over a string until given character or '\0' is found
class char_sentinel
{
public:
char_sentinel(char end) :
end_character(end)
{ }
friend bool operator==(const char* lhs, char_sentinel rhs)
{
return (*lhs == '\0') || (*lhs == rhs.end_character);
}
friend bool operator!=(const char* lhs, char_sentinel rhs) { ... }
friend bool operator==(char_sentinel lhs, const char* rhs) { ... }
friend bool operator!=(char_sentinel lhs, const char* rhs) { ... }
private:
char end_character;
}; …Run Code Online (Sandbox Code Playgroud) 如何测试概念模板参数中是否存在成员类型,即 for typename Container、 test for Container::reverse_iterator?正确的要求子句是什么?
在可变参数模板参数之前我们可以有可变参数概念吗?
我的意思是,遵循法律:
template <class, std::size_t> concept Any = true;
template <class> struct n_ary;
template <std::size_t... Is>
struct n_ary<std::index_sequence<Is...>>
{
template <Any<Is>... Ls, typename ... Ts>
void operator()(Ls..., Ts...) {}
};
Run Code Online (Sandbox Code Playgroud)
演示(仅 clang 接受)
注意:如果没有 extra Ts,所有编译器都接受Demo。
std::common_type<T1, ..., TN>T1是 C++ 中的一个辅助模板,它可以找到所有...TN都可以隐式转换为的通用类型。
根据 C++ 规范,如果某些条件适用,用户可以专门化std::common_type<T1,T2>,并且:
std::common_type<T1, T2>::type并且std::common_type<T2, T1>::type必须表示相同的类型。
然而,common_type<T1, T2>对于用户类型来说,可能是一个非常复杂的专业化,T1并且T2:
namespace std {
template <typename T1, complicated_constraint_of<T1> T2, ...>
struct common_type<complicated_expression_of<T1, ...>, complicated_expression_of<T2, ...>> {
using type = complicated_type_expression_of<T1,T2>;
};
}
Run Code Online (Sandbox Code Playgroud)
一般来说,约束表达式不一定是对称的(例如,我们可以指定 是T2的底T1)。这意味着为了保持对称性,我们需要用T1和T2反转来重写整个特化,但在不犯任何错误的情况下做到这一点是极其困难和脆弱的。
如何common_type<T1,T2>为我自己的类型稳健地定义 的交换特化?
c++ ×10
c++-concepts ×10
c++20 ×6
c++17 ×2
templates ×2
c++11 ×1
class ×1
std ×1
type-traits ×1