这可能听起来像一个愚蠢的问题,但我想知道很长一段时间有一个更好的方法:
struct X
{
int a;
int b;
};
bool sortComp(const X first, const X second)
{
if (first.a!=second.a)
return (first.a<second.a);
else
return (first.b<second.b);
}
class setComp
{
public:
bool operator() (const X first, const X second) const
{
if (first.a!=second.a)
return (first.a<second.a);
else
return (first.b<second.b);
}
};
int main()
{
vector<X> v;
set<X, setComp> s;
sort(begin(v), end(v),sortComp);
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我实现了两次相同的功能,一次用于排序,一次用于集合中的隐式排序.有没有办法避免代码重复?
我使用g ++ 4.6,我试图根据使用的char类型模拟我的类,但我的变量不仅仅是字符,而是字符串的字符串.所以我尝试过这样的事情:
template<typename T>
class Node
//...
//constructor
Node(std::basic_string<T> str, std::basic_string<T>::iterator it)
{
}
//usage
Node<char16_t> start;
Run Code Online (Sandbox Code Playgroud)
但我得到'std :: basic_string <_CharT,std :: char_traits <_CharT>,std :: allocator <_Tp1 >> :: iterator'不是类型
当我在构造函数arg列表中替换第二个T为char16_t时它编译.
虽然谷歌搜索如何重载operator =我发现一些例子返回值 http://www.cprogramming.com/tutorial/operator_overloading.html
,而我的朋友很久以前就是C++ guru告诉我返回引用.另外,例如当我查看STL源代码时,我看到了类似的东西:
vector&
operator=(const vector& __x);
Run Code Online (Sandbox Code Playgroud)
那么这样做的正确方法是什么?
顺便说一句,如果你很好奇我的朋友告诉我,返回ref的原因是因为内置类型返回l值.
int x;
(x = 3) += 2;
// x is now 5.
Run Code Online (Sandbox Code Playgroud) 同事和我讨论了一个假想的问题,当一个人想要实现自旋锁互斥std::atomic_flag,但也实现那个自旋锁而不是(真)但作为一个
while(true)
{
cnt=0;
while (cnt<yieldAfterTries)
{
//try to get lock
cnt++;
}
std::this_thread::yield();
// if got lock do work and then break;
}
Run Code Online (Sandbox Code Playgroud)
基本上的想法是线程不能"很长一段时间"阻止其他人,即使它有一个实时优先级,因为它会在一段时间后产生...但是当我看到std :: yield的规范时我很惊讶它是一个建议,不是强制性的.
提供实现的提示,以重新安排线程的执行,允许其他线程运行.
http://en.cppreference.com/w/cpp/thread/yield
那会有问题吗?
同事(严肃地说,我不使用char*:))制作了一个减少到这个的bug:
testVar.append('\0'); //testVar is std::string
Run Code Online (Sandbox Code Playgroud)
所以他基本上修复了它:
testVar.append("\0");
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么第一个不合法?不能认为它是0长度0终止字符串?我尝试进入VS10 std lib实现,亲眼看看,但我后悔了.:)
我了解一致性参数,但是模板的大多数参数都是类型,因此我认为,由于lambda旨在简化定义结构的方式,它可能应该默认为typename/ class(您仍然需要编写int/size_t/short)。
如果有人不熟悉C ++ 20中对lambda的更改,请参考以下示例:
[]<typename T>(const std::vector<T>& v)
{
for(const auto& x : v) { std::cout << x; }
};
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么不这样做:
[]<T>(const std::vector<T>& v)
{
for(const auto& x : v) { std::cout << x; }
};
Run Code Online (Sandbox Code Playgroud) C ++ 20 lambdas获得了一项新功能(纸张p0428r2。),您可以将其指定<typename T>为正常功能。阅读该纸张时,我注意到一个示例:
auto f = []<typenameT>(std::vector<T> vector) { /* ... */ };
Run Code Online (Sandbox Code Playgroud)
那让我开始思考:
为什么语言不能“弄清楚” T是一种类型(因为std :: vector是一个模板,期望里面包含type参数<>)。
auto f = [](std::vector<T> vector) { /* T deduced ... */ };
Run Code Online (Sandbox Code Playgroud)
是否有技术上的限制来防止这种情况发生?使用案例是否太晦涩/稀少,以至于不能为其保证语言规则?
考虑以下代码:
#include<functional>
#include<iostream>
#include<map>
const std::map<int, std::string> numberToStr{{1, "one"}, {2,"two"}};
int main() {
auto it = numberToStr.find(2);
if (it ==numberToStr.end()){
return 1;
}
const auto&[_, str] = *it;
std::cout << str;
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以让我解开it对 2 个可选项(_ 和 str)的潜在解引用,然后我可以写:
const auto&[_, str] = // some magic;
// _ is std::optional<int>, str is std::optional<str>
if (!str){
return 1;
}
std::cout << *str;
}
Run Code Online (Sandbox Code Playgroud)
我认为不是,因为结构化绑定是语言级别的东西,并且 std::optional 是一个库功能,并且 afaik 无法自定义交互。
注意:我想我可以实现我自己的映射,它返回知道它们是否指向 .end() 的迭代器,并“hack”自定义点以基于此执行可选逻辑,当我不控制时,我要求使用一般用例容器。
我知道我可以使用reinterpret_cast,但是我不能从 char 转换为像 std::byte 这样的“通用”类型似乎很奇怪。这只是不幸的错误/限制,还是有原因?
示例:
int main(){
std::string s{"abc"};
std::byte* ptr = static_cast<std::byte*>(s.data());
}
Run Code Online (Sandbox Code Playgroud)