Hey I'm trying to design some Interfaces without any runtime overhead using c++20 concepts.
I came up with the following (simplified) concept
/**
* @brief This concept defines an OSA Interface
*/
template<typename T, typename Task_T>
concept OSA_Layer_T = requires (T a) {
{T::getName(a)} -> std::same_as<std::string>; ///< Returns the name of the task (if no name is available return the ID as string)
{T::getId(a)} ->std::same_as<Task_T>; ///< returns the (underlying) ID of the task
};
Run Code Online (Sandbox Code Playgroud)
Since every OS has it's own …
概念或约束的正确位置在哪里?
\n以下代码编译:
\nvoid f(int x) { } \n\ntemplate <typename T>\nconcept Concept =\n requires (T a)\n { f(a); };\n\n\ntemplate <typename T>\n requires Concept<T>\nstruct A\n{ };\n\n\n\nint main(){\n A<int> a;\n}\nRun Code Online (Sandbox Code Playgroud)\n但如果我将函数的位置更改f(int)为:
template <typename T>\nconcept Concept =\n requires (T a)\n { f(a); };\n\n\nvoid f(int x) { } // <-- new position\n\ntemplate <typename T>\n requires Concept<T>\nstruct A\n{ };\n\n\n\nint main(){\n A<int> a;\n}\nRun Code Online (Sandbox Code Playgroud)\n这不能在 gcc 11.3.0 中编译。我收到以下错误:
\nmain.cpp:27:10: error: template constraint failure for \xe2\x80\x98template<class T> requires Concept<T> struct A\xe2\x80\x99\n …Run Code Online (Sandbox Code Playgroud) 根据convertible_to中的 en.cppreference.com :
概念convertible_to<From, To>指定与std::declval()相同类型和值类别的表达式可以隐式和显式转换为To类型,并且两种转换形式是等效的。
我理解这意味着如果有成员,该convertible_to概念将被识别convertible_to<U, V>为满意。即使运算符是显式的而不是隐式运算符。Uexplicit operator V()
但是我发现msvc中不是这样的。
由于静态断言,以下代码无法编译:
#include <concepts>
#include <iostream>
class ExplictClass
{
public:
inline explicit operator int() const
{
return 5;
}
};
int main()
{
static_assert(std::convertible_to<ExplictClass, int>, "Explicit not convertible?"); // Fails here, concept not satisfied.
}
Run Code Online (Sandbox Code Playgroud)
这是我对概念的误解std::convertible_to,代码中的错误,还是 en.cppreference.com 中的错误,或者 msvc v19 的不一致性。
附上使用 x64 msvc v19.latest 的编译器资源管理器的链接,其中包含上述代码
编辑:
实际需要convertible_to是生成一个to_string函数模板,该模板可以与声明的可转换类型很好地配合,如下所示:
template<class T>
std::string to_string(T val)
{
std::ostringstream stream; …Run Code Online (Sandbox Code Playgroud) 在以下代码中,它在 -std=c++23 标志下编译。为什么概念要求 In 参数不应被引用触发?
#include <concepts>
#include <type_traits>
#include <functional>
template <typename T>
concept NotRef = requires { !std::is_reference_v<T>; };
template <typename In, typename Out>
requires NotRef<In> // requires that In should not be reference
class SwitchType
{
using ConstIn = std::add_const_t<In>;
public:
SwitchType(const In& in)
: in_{in}
{ }
ConstIn & in_;
};
int main()
{
int a{9};
// Expected behavior: 'requirement not satifsfied'
// Actural behavior: compiles under c++ 23
SwitchType<int&, int> mytype{a};
}
Run Code Online (Sandbox Code Playgroud) 以下代码是否需要 T 的隐式复制构造函数,因为参数是按值传递的?或者它的行为类似于 decltype 并且不涉及真正的构造?
template<typename T>
concept Addable = requires (T a, T b){ a + b; };
Run Code Online (Sandbox Code Playgroud) My goal is to have a generic way to traverse a std::tuple, and the following code tries to show it:
#include <iostream>
#include <tuple>
template <typename t, size_t t_idx, typename t_tuple>
concept visit_tuple_element_value = requires(t &&p_t, const t_tuple &p_tuple) {
{
p_t.template operator()<t_idx>(
std::declval<std::add_const_t<std::add_lvalue_reference_t<t_tuple>>>())
} -> std::same_as<bool>;
};
template <typename t_tuple, typename t_function, size_t t_idx = 0>
requires(visit_tuple_element_value<t_function, t_idx, t_tuple>)
void traverse_tuple_values(t_function p_function, const t_tuple &p_tuple) {
if constexpr (t_idx < std::tuple_size_v<t_tuple>) {
if (p_function.template operator()<t_idx>(p_tuple)) {
traverse_tuple_values<t_tuple, t_function, …Run Code Online (Sandbox Code Playgroud) 我如何要求和检查的说法是有一定概念的C++?
例如,标头中的random_shuffle函数algorithm要求其参数是RandomAccessIterators:
template<typename _RandomAccessIterator>
inline void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
}
Run Code Online (Sandbox Code Playgroud)
我想我不能__glibcxx_function_requires在我自己的代码中使用这些等等?他们是如何工作的?你在代码中检查这样的东西吗?
我有一组用作模板参数的类.它们都符合一些非正式的界面(又名概念)
template <typename T>
int func( T& t ) { return t.a() + t.b() + t.c(); }
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我们说我使用Foo或Bar作为参数实例化模板,因此他们必须实现方法a b和c.
struct Foo { int a(); int b(); int c(); };
struct Bar { int a(); int b(); int c(); };
Run Code Online (Sandbox Code Playgroud)
现在,我有很多这样的类,我希望有一个函数的默认实现方式.
例如,我想c返回的区别a()和b()默认.所以,我希望,这将是足够的,我定义a()和b()而c()作为将自动执行int c() { return a()- b();},而无需复制此代码的所有类.
我过去通过多态来实现这个结果(通过在基类中定义a()和b()使用默认(虚拟)实现的纯虚函数c()),但出于性能原因,我放弃了这种机制.
我想知道是否有一个推荐的解决方案来获得这种结果(即使用我的模板参数类编写一次默认实现).
继续我读取range-v3库,我意识到关于模板类型的有效表达式的所有检查都有一个拖尾",42"表达式,我想知道它的目的是什么.例如:
namespace concepts {
constexpr struct valid_expr
{
template<typename... T>
void operator()(T&&...) const;
};
}
struct ExplicitlyConvertibleTo
{
template<typename From, typename To>
auto requires_(From (&from)()) -> decltype(
concepts::valid_expr(
((void) static_cast<To>(from()), 42)
));
};
Run Code Online (Sandbox Code Playgroud)
我理解该实现的一些要点,比如强制使用逗号运算符的内括号,避免逗号运算符的一些重载等的void-casting,但为什么不只是简单地写一些像?
concepts::valid_expr(static_cast<To>(from()));
Run Code Online (Sandbox Code Playgroud) 我试图移植一些我在ubuntu上制作的C++ 17代码(gnu ++ 11)
typedef boost::variant<int, float, std::string > Variant;
using Func = std::function<std::vector<unsigned char>(std::vector<Variant>)>;
void addexecutorfunc( Func callback, const auto&...args )
{
std::vector<Variant> vec = {args...};
executor.add(vec, std::move(callback));
}
Run Code Online (Sandbox Code Playgroud)
这段代码在ubuntu上编译和工作正常,但是当尝试使用visual studio 2017(v141)[ISO C++最新草案标准(/ std:c ++ latest)]在Windows上编译时,我得到以下内容:
错误C3533:参数不能包含'auto'的类型
我想也许它与在当前的C++ 17版本中没有实现的Concepts lite有关,或者这是错的?
如果我可以设置编译器使用auto作为参数和参数包,那么这将是最好的,但如果这是不可能的,那么我将不得不重写我的代码遵循C++ 17 windows标准 - 任何关于如何做的建议这没有在模板地狱中结束