为了允许std::string从std::string_view模板构造函数进行构造
template<class T>
explicit basic_string(const T& t, const Allocator& alloc = Allocator());
Run Code Online (Sandbox Code Playgroud)
const T&仅当可转换为std::basic_string_view<CharT, Traits>(链接)时才启用。
同时有专门的推演指南可以推演basic_string(basic_string_view链接)。该指南的评论说:
需要指南 (2-3),因为 std::basic_string_views 的 std::basic_string 构造函数被制作为模板,以避免在现有代码中引起歧义,并且这些模板不支持类模板参数推导。
所以我很好奇,需要有演绎指南和模板构造函数而不是简单的构造函数的歧义是什么std::basic_string_view,例如类似的东西
explicit basic_string(basic_string_view<CharT, Traits> sv, const Allocator& alloc = Allocator());
Run Code Online (Sandbox Code Playgroud)
请注意,我并不是问为什么构造函数被标记为显式。
一些std::optional 构造函数使用这样的std::in_place_t标记参数:
template< class... Args >
explicit optional( std::in_place_t, Args&&... args );
Run Code Online (Sandbox Code Playgroud)
我看到这样的构造函数可以在没有就地标记的情况下实现,并使用一些enable-if魔法不参与不愿意的重载,即简单地说:
template< class... Args >
explicit optional( Args&&... args );
Run Code Online (Sandbox Code Playgroud)
为什么std::optional使用就地标记实现就地构造函数而不是一些启用魔法(并且没有标记)?
更新:问题略有更新,以强调我意识到简单地省略就地标记是行不通的.
当您拥有unique_ptr由引用存储的自定义删除器时,对该案例进行成像:
struct CountingDeleter
{
void operator()(std::string *p) {
++cntr_;
delete p;
}
unsigned long cntr_ = 0;
};
int main()
{
CountingDeleter d1{}, d2{};
{
std::unique_ptr<std::string, CountingDeleter&>
p1(new std::string{"first"} , d1),
p2(new std::string{"second"}, d2);
p1 = std::move(p2); // does d1 = d2 under cover
}
std::cout << "d1 " << d1.cntr_ << "\n"; // output: d1 1
std::cout << "d2 " << d2.cntr_ << "\n"; // output: d2 0
}
Run Code Online (Sandbox Code Playgroud)
这是一个惊喜,我在上面的代码分配具有复制的副作用d2成d1.我仔细检查了一下,发现这种行为与[unique.ptr.single.asgn]中的标准一样 …
不同的C ++功能的编译时间是多少?我有兴趣选择正确的方法来在我的库头文件中实现一些通用代码,并且我想花一些时间为图书馆用户考虑。粗略和/或相对的数字就可以了。
我对以下情况特别感兴趣:
{ return true; })PS:请不要谈论我过早的优化。无论如何,有关编译时间的信息将对C ++开发人员很有趣。
更新:阐明了我正在优化的代码在库头文件中,因此其编译时间对于库用户而言绝对重要。
更新:改写该问题以免引起别人的疑问。
c++ ×4
c++17 ×2
c++11 ×1
compilation ×1
constexpr ×1
stdoptional ×1
string ×1
string-view ×1
templates ×1
unique-ptr ×1