我想编写一个模板函数,只能使用2个数字(例如3和5),如果你尝试将它与其他数字一起使用,则会给出错误.
我可以这样做:
template<int x>
void f();
template<>
void f<3>()
{
cout << "f<3>()\n";
}
template<>
void f<5>()
{
cout << "f<5>()\n";
}
Run Code Online (Sandbox Code Playgroud)
然后我可以正常方式调用此函数:
f<3>();
f<5>();
Run Code Online (Sandbox Code Playgroud)
它编译得很好,如果我尝试错误地使用我的函数:
f<10>();
Run Code Online (Sandbox Code Playgroud)
编译器给我一个错误.
我有这个方法的2个问题:
1.-这是标准吗?我可以使用整数专门设计模板吗?
2.-我不喜欢你使用这种方法时得到的错误,因为错误并没有告诉用户他做错了什么.我更喜欢这样写:
template<int x>
void f()
{
static_assert(false, "You are trying to use f with the wrong numbers");
}
Run Code Online (Sandbox Code Playgroud)
但这不编译.看来我的编译器(gcc 5.4.0)试图首先实例化主模板,因此它给出了(static_assert的)错误.
谢谢您的帮助.
如果您想知道我为什么要这样做是因为我正在学习如何编程微控制器.在微控制器中,你有一些只做一些事情的引脚.例如,引脚3和5是可以生成方波的引脚.如果在一个应用程序中我想生成一个方波,我想写下这样的东西:
square_wave<3>(frecuency);
Run Code Online (Sandbox Code Playgroud)
但是,如果几个月后我想在另一个使用不同微控制器的应用程序中重用这个代码(或更改它),我希望我的编译器对我说:"呃,在这个微控制器中你不能在引脚3中产生方波而5.使用引脚7和9".我认为这可以为我节省很多麻烦(或许不是,我真的不知道.我只是学习如何编程微控制器).
c++ microcontroller templates static-assert template-specialization
如果满足以下条件,则以下代码可完美编译:
我不包括<iostream>或
我命名operator==为alp::operator==。
我想有一个问题<iostream>和operator==,但我不知道是什么。
我用gcc 7.3.0,clang ++-6.0和goldbolt编译代码。总是相同的错误。
问题在于编译器正在尝试将to的参数转换operator==为const_iterator,但是为什么呢?(我想编译器看不到我的版本,而是在operator==寻找其他版本)。
#include <vector>
#include <iostream> // comment and compile
namespace alp{
template <typename It_base>
struct Iterator {
using const_iterator = Iterator<typename It_base::const_iterator>;
operator const_iterator() { return const_iterator{}; }
};
template <typename It_base>
bool operator==(const Iterator<It_base>& x, const Iterator<It_base>& y)
{ return true;}
}// namespace
struct Func{
int& operator()(int& p) const {return p;}
};
template <typename It, typename …Run Code Online (Sandbox Code Playgroud) 概念或约束的正确位置在哪里?
\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) 如果你想编写一个迭代器,你通常会写
T* operator->() const;
Run Code Online (Sandbox Code Playgroud)
我的问题是用指针和引用理解这个"const".
例如,您可以编写以下结构:
struct A{
int* x;
A(int& x0):x{&x0}{}
int* ptr() const {return x;}
int& ref() const {return *x;}
};
Run Code Online (Sandbox Code Playgroud)
你可以这样使用它:
int x = 10;
const A a{x};
int& r = a.ref();
int* p = a.ptr();
*p = 4;
cout << x << endl; // prints 4
r = 25;
cout << x << endl; // prints 25
Run Code Online (Sandbox Code Playgroud)
但是为什么这个编译并正常工作(至少用g ++和clang).为什么?
正如我所定义
const A a{x};
Run Code Online (Sandbox Code Playgroud)
这个"a"是const.所以我打电话的时候
int* p = a.ptr();
Run Code Online (Sandbox Code Playgroud)
我用const对象调用ptr(),因此内部指针A-> x必须是"int*const".但是我返回一个没有const的"int*".为什么这是正确的?
参考会发生什么?如果我用"const A"调用A :: ref(),这个函数返回的类型是什么?像"int&const"之类的东西??? <---我想这与"int&"相同.
谢谢你的帮助.
根据 C++ 标准草案,执行std::iter_value_t必须是:
\n\n使用 iter_value_t 的模板=见下文;
\n让 RI 成为
\nremove_cvref_t<I>。类型iter_value_t<I>表示(2.1)\xe2\x80\x94
\nindirectly_readable_traits<RI >::value_type如果iterator_traits<RI>命名从主模板生成的专业化,并且(2.2)\xe2\x80\x94
\niterator_traits<RI >::value_type否则。
我明白那个:
\ntype iter_value<T>: // OK, this is not C++, is to clarify my question\n type R = remove_cvref_t<T>;\n if (iterator_traits<R> is a specialization of iterator_traits)\n return indirectly_readable_traits<R>::value_type;\n else\n return iterator_traits<R>::value_type;\nRun Code Online (Sandbox Code Playgroud)\n但在cppreference中,实现必须是:
\n\n计算
value typeT 的 。如果std::iterator_traits<std::remove_cvref_t<T>>不是专门化的,则为std::iter_value_t<T> …
当函数需要返回两个参数时,可以使用std :: pair编写它:
std::pair<int, int> f()
{return std::make_pair(1,2);}
Run Code Online (Sandbox Code Playgroud)
如果你想使用它,你可以这样写:
int one, two;
std::tie(one, two) = f();
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是你需要定义'one'和'two'然后将它们分配给f()的返回值.如果我们能写出类似的东西会更好
auto {one, two} = f();
Run Code Online (Sandbox Code Playgroud)
我看了一个演讲(我不记得哪一个,对不起),演讲者说C++标准的人试图做那样的事情.我认为这个讲座是从2年前开始的.有谁知道现在(几乎是c ++ 17)你能做到或类似吗?
下面的代码
template <typename T>
struct A
{ static void f() {std::cout << "A<T>\n";} };
template <typename T>
struct A<const T>
{ static void f() {std::cout << "A<const T>\n";} };
template <typename T>
struct A<const T*>
{ static void f() {std::cout << "A<const T*>\n";} };
template <typename T>
void f()
{
A<const T>::f();
}
int main()
{
f<const int*>();
}
Run Code Online (Sandbox Code Playgroud)
没有像我预期的那样工作。
我(错误地)认为对 call 的调用在本例中是f<const int*>()函数并且折叠成. 但这不是程序所做的,因为它打印的意思是(实际上)折叠成.A<const T>::f()A<const const int*>:f()const const int*const int*A<const T>const …