以下代码由于隐式转换而编译char
.我不知道为什么,因为唯一的隐式转换我希望(并期望失败)是从char const*
到size_t
.
#include <cstddef>
struct foo
{
int operator[](size_t i) const { return 1; }
operator char() const { return 'a'; }
};
int main()
{
foo f;
f["hello"]; // compilation error desired here
}
Run Code Online (Sandbox Code Playgroud)
什么是允许这个编译的隐式转换?如果我删除operator char
或制作它,explicit
则编译在所需位置失败.
提取此代码的类确实需要隐式转换和operator[]
.那么有没有一种方法可以防止行为而不使转换明确?
给定一个自定义类型,下面的片段显示了允许函数自动选择特定于该类型的用户提供的重载的常用方法,或者如果没有,则显示标准库中的函数的泛型实现.
// assume std::foo is a real function template returning an int
namespace a {
struct b { };
int foo(b& ab) { ... }
}
int bar(a::b& ab)
{
using std::foo;
return foo(ab);
}
Run Code Online (Sandbox Code Playgroud)
这种方法会自动选择a::foo
优先于std::foo
(如果存在).
我的问题是,当有问题的调用是构造函数初始化列表的一部分时,是否有可能实现类似的行为?
struct bar2
{
bar2(a::b& ab);
int i;
};
bar2::bar2(a::b& ab)
: i{foo(ab)} // want a::foo if available, else std::foo
{ }
Run Code Online (Sandbox Code Playgroud)
显然,放入using std::foo
构造函数体内为时已晚.但是,如果我把它放在构造函数定义之前,我会引入std::foo
全局命名空间,这也是不可取的.
在这种情况下,有没有办法让两全其美?
我正在编写一个模板,它真正需要了解其参数类型的所有基类.该std::bases
提议特点N2965非常适合这一点,但是我无法找到有关其状态的任何可靠的信息.
这个提案还活着吗?如果是这样,我们什么时候可能会看到它,标准化?如果没有,是否有任何其他提议可以提供这种能力?
作为后续,G ++具有可作为两个N2965特质std::tr2::bases
和std::tr2::direct_bases
.Clang和/或Intel是否有任何可以提供同等功能的扩展?
我有一个结构模板,它采用两种类型(T
和S
),并在某些时候使用a static_cast
从一种类型转换为另一种类型.它往往是那么回事T
,并S
属于同一类型.
设置的简化示例:
template <typename T, typename S = T>
struct foo
{
void bar(T val)
{
/* ... */
some_other_function(static_cast<S>(val));
/* ... */
}
};
Run Code Online (Sandbox Code Playgroud)
在S
与类相同的情况下,是否T
可以static_cast
引入额外的开销,或者它是否总是被忽略的空操作?
如果它确实引入了开销,是否有一个简单的模板元编程技巧,static_cast
只在需要时执行,或者我是否需要创建部分特化以应对T == S
案例?foo
如果可能的话,我宁愿避免整个模板的部分特化.
以下结构无法在C++ 11下编译,因为我已将移动赋值运算符声明为noexcept
:
struct foo
{
std::vector<int> data;
foo& operator=(foo&&) noexcept = default;
};
Run Code Online (Sandbox Code Playgroud)
编译器生成的默认移动赋值运算符是noexcept(false)
由于std::vector<int>
移动赋值也是如此noexcept(false)
.这反过来是由于默认分配器已std::allocator_traits<T>:: propagate_on_container_move_assignment
设置为std::false_type
.另见这个问题.
我的问题是,有没有办法强制noexcept
使用默认的移动赋值赋值运算符而不必自己定义它?
如果这是不可能的,是有办法,我可以欺骗std::vector<int>
应运而生noexcept
举动分配,以便noexcept(true)
通过传递给我的结构?
出于好奇,我想知道标准__TIME__
预处理器宏给出的值是否可以在单个翻译单元中改变?
换句话说,__TIME__
在预处理期间确定一次然后固定,还是每次遇到它时重新评估?
如果C标准没有规定,主要实现(gnu,clang,intel,msvc)中是否存在事实上的标准行为?
C++属性提供了一种方便且标准化的方法来标记代码,并提供额外的信息以提供给编译器和/或其他工具.
使用OpenMP涉及#pragma omp...
在源中添加许多行(例如标记循环以进行并行处理).这些#pragma
线似乎是广义属性等设施的绝佳候选者.
例如,#pragma omp parallel for
可能会成为[[omp::parallel(for)]]
.
通常不准确的cppreference.com 在这里使用这样的属性作为示例,这确认它至少被某人考虑过.
是否存在OpenMP pragma到当前可用并且由任何/所有主要编译器支持的C++属性的映射?如果没有,是否有任何计划正在创建一个?
C++ 11标准指定了一个std::alignment_of<T>
简单返回值的类型特征alignof(T)
.
sizeof
运营商是否有类似的特征?我只是错过了它,还是只是错过了标准,还是有一些模糊的技术原因为什么没有指定?
显然创造这样一个特征是微不足道的,但我无法想象在介绍时不会考虑它std::alignment_of
.
对于上下文,我有一个自定义类型特征,用于在应用于类型列表时获取单个特征的最大值.
template <template<class> class Trait, typename F, typename... T>
struct trait_max
: std::integral_constant<decltype(Trait<F>::value),
(Trait<F>::value > trait_max<Trait, T...>::value) ? Trait<F>::value : trait_max<Trait, T...>::value>
{ };
template <template<class> class Trait, typename F>
struct trait_max<Trait, F>
: std::integral_constant<decltype(Trait<F>::value), Trait<F>::value>
{ };
Run Code Online (Sandbox Code Playgroud)
当你需要知道一组类型的最大值时,这个特性非常方便:
auto max_align = traits_max<std::alignment_of, int, float, std::string>::value;
auto max_size = traits_max<std::size_of, int, float, std::string>::value; // doesn't exist
Run Code Online (Sandbox Code Playgroud) 鉴于这std::chrono::duration
可以代表两次之间的有符号差异,那么需要这种持续时间的绝对值似乎是非常普遍的情况.例如,以下代码diff: -5
按预期输出:
using namespace std;
using namespace std::chrono;
auto now = system_clock::now();
auto then = now - seconds(5);
auto diff = then - now;
cout << "diff: " << duration_cast<seconds>(diff).count() << endl;
Run Code Online (Sandbox Code Playgroud)
能做这样的事情会很高兴:
auto diff = abs(then - now);
Run Code Online (Sandbox Code Playgroud)
不过,我看不到任何专业化std::abs
的chrono
标准模板,也没有我可以看到在任何适当的成员函数std::chrono::duration
.
我应该如何将其转化std::chrono::duration
为绝对价值?
C++标准(github.com/cplusplus/draft)具有time_t
转换函数(std::chrono::system_clock::to_time_t
和std::chrono::system_clock::from_time_t
)对列为static
和noexcept
但不是constexpr
.
由于基本上所有的操作对time_point
与duration
被constexpr
(包括duration_cast
和time_point_cast
),我想不出任何理由将它们排除在外.快速检查本地计算机上的libstdc ++源代码确认这些函数是作为简单的duration/time_point强制转换实现的.
这两个功能不应该是什么原因constexpr
吗?这只是"因为没有人提出他们应该"的情况吗?