我尝试实现一个类似于std::is_constructable
的值模板,但只有当类型在constexpr环境中可复制时才为true(即其复制构造函数是constexpr限定的)。我得出了以下代码:
#include <type_traits>
struct Foo {
constexpr Foo() = default;
constexpr Foo(const Foo&) = default;
};
struct Bar {
constexpr Bar() = default;
Bar(const Bar&);
};
namespace detail {
template <int> using Sink = std::true_type;
template<typename T> constexpr auto constexpr_copiable(int) -> Sink<(T(T()),0)>;
template<typename T> constexpr auto constexpr_copiable(...) -> std::false_type;
}
template<typename T> struct is_constexpr_copiable : decltype(detail::constexpr_copiable<T>(0)){ };
static_assert( is_constexpr_copiable<Foo>::value, "");
static_assert(!is_constexpr_copiable<Bar>::value, "");
现在我问自己这是否符合标准,因为编译器似乎不同意输出。https://godbolt.org/g/aaqoah
编辑(C++17个功能):
在使用C++17的新的自动非类型模板类型实现略有不同的is_constexpr_constructible_from
时,当用sfinae
取消引用constexpr表达式中的nullptr时,我再次发现了编译器之间的差异。
#include <type_traits>
struct Foo {
constexpr Foo() = default;
constexpr Foo(const Foo&) = default;
constexpr Foo(const Foo*f):Foo(*f) {};
};
struct Bar {
constexpr Bar() = default;
Bar(const Bar&);
};
namespace detail {
template <int> struct Sink { using type = std::true_type; };
template<typename T, auto... t> constexpr auto constexpr_constructible_from(int) -> typename Sink<(T(t...),0)>::type;
template<typename T, auto... t> constexpr auto constexpr_constructible_from(...) -> std::false_type;
}
template<typename T, auto... t> struct is_constexpr_constructible_from : decltype(detail::constexpr_constructible_from<T, t...>(0)){ };
constexpr Foo foo;
constexpr Bar bar;
static_assert( is_constexpr_constructible_from<Foo, &foo>::value, "");
static_assert(!is_constexpr_constructible_from<Foo, nullptr>::value, "");
static_assert(!is_constexpr_constructible_from<Bar, &bar>::value, "");
int main() {}
Clang接受一些未定义的行为,即在decltype
的未求值操作数的求值中取消引用nullptr
。
最难的挑战是,给出一个函数来评估从const T&
中是否存在任意T的constexpr
构造函数,这里给出的在C++17中似乎是不可能的。幸运的是,我们可以有很长的路没有。其理由如下:
以下限制对于确定某些表达式是否可以在constexpr
内容中求值很重要:
>
要计算t
的复制构造函数,需要const t&
类型的值。这样的值必须引用具有活动生存期的对象,即在constexpr
上下文中,它必须引用在逻辑封闭表达式中创建的某个值。
这可能会给我们一个小漏洞
所以表达式最好是未求值的操作数§8.2.3.1
在某些上下文中,会出现未求值的操作数([expr.prim.req]、[expr.typeid]、[expr.sizeof]、[expr.unary.noexcept]、[dcl.type.simple]、[temp])。未求值的操作数不求值
不幸的是,新引入的if constexpr
不是表达式,而是带有表达式参数的语句。因此,它不能帮助强制表达式的constexpr
可求值性。当语句被计算时,它的表达式也被计算,我们又回到了创建一个可计算的常量t&
的问题上。丢弃的语句对进程没有任何影响。
由于困难的部分是创建常量t&
,所以我们只针对少量常见但容易确定的可能性进行创建,其余的则由非常特殊的case调用者进行专门化。
namespace detail {
template <int> using Sink = std::true_type;
template<typename T,bool SFINAE=true> struct ConstexprDefault;
template<typename T>
struct ConstexprDefault<T, Sink<(T{}, 0)>::value> { inline static constexpr T instance = {}; };
template<typename T> constexpr auto constexpr_copiable(int) -> Sink<(T{ConstexprDefault<T>::instance}, 0)>;
template<typename T> constexpr auto constexpr_copiable(...) -> std::false_type;
}
template<typename T>
using is_constexpr_copyable_t = decltype(detail::constexpr_copiable<T>(0));
专用化详细信息::ConstExprDefault
对于声明constexpr复制构造函数的任何类类型都是可能的,如上所示。请注意,该参数对于其他没有构造函数的复合类型不成立§6.7.2。数组、联合、引用和枚举需要特别注意。
为什么只有很多?与前面一样,一些constexpr构造函数将存在,但可能有访问限制。这将在我们的模板机中给出一个假阳性,并导致无限的搜索,并且在某个时候编译器会死:/。或者构造函数可能被无法解析的重载隐藏,因为ubiq
太通用。同样的效果,可悲的编译器和一个愤怒的petc
(™善待编译器组织,不是一个真正的组织)。实际上,访问限制可能是可以解决的,因为这些限制并不应用在模板参数中,而模板参数可能允许我们提取一个指向成员的指针和[...]。
我就到此为止。据我所知,这是乏味的,而且大部分是不必要的。当然,包含5个参数的可能的构造函数调用对于大多数用例来说已经足够了。任意t
是非常非常困难的,我们不妨等待C++20,因为模板元编程将再次发生巨大变化。
问题内容: 我正在学习Java,但是在和接口上找不到任何好的解释。 当我实现an时,我的Eclipse IDE创建了一个方法。 我可以在没有界面的情况下关闭流。但是,我不明白如何使用接口实现该方法。而且,此接口的目的是什么? 我也想知道:如何检查是否真的关闭? 我正在使用下面的基本代码 问题答案: 在我看来,您对接口不是很熟悉。在您发布的代码中,您无需实现。 您仅需要(或应该)实现,或者如果您将要
SPDY 使用 TLS 的扩展称为 Next Protocol Negotiation (NPN)。在Java 中,我们有两种不同的方式选择的基于 NPN 的协议: 使用 ssl_npn,NPN 的开源 SSL 提供者。 使用通过 Jetty 的 NPN 扩展库。 在这个例子中使用 Jetty 库。如果你想使用 ssl_npn,请参阅https://github.com/benmmurphy/ss
> 我知道Sqoop中可用的选项,但如果我是正确的,我想知道Sqoop是如何在实时实现中使用的(通常) 1.1sqoop命令放在shell脚本中,从调度程序/事件触发器调用。我可以有实时代码-这方面的例子,特别是在shell脚本中向Sqoop动态传递参数(如表名)。 1.2相信Ooozie工作流也可以使用。请举例说明 抱歉问了太多问题。我没有看到任何关于如何在实时场景中使用这些组件的文章/博客。
问题内容: 今天,我有一个采访上,我问候选人很平常和基本的问题有关的区别和。我以为他会回答类似这样的,但他说,这些方法基本上是一样的,而且极有可能是用在它里面,但本身并不需要外部锁。这不是完全正确的答案,因为在JDK 1.6中此方法具有以下签名。 但是我的第二个想法是,这不是那么可笑。可以使用定时等待来达到相同的效果。看一下以下代码片段: 在这种情况下,一个对象特别用于同步块内部方法。我假设Sun
Web套接字不仅在Web中而且在移动行业中都发挥着关键作用。Web套接字的重要性如下。 Web套接字(如名称所示)与Web相关。Web由一些浏览器的技术组成; 它是广泛的通信平台,适用于大量设备,包括台式电脑,笔记本电脑,平板电脑和智能手机。 利用Web套接字的HTML5应用程序可以在任何支持HTML5的Web浏览器上运行。 主流操作系统支持Web套接字。移动行业的所有主要参与者都在自己的原生应用
问题内容: 考虑以下代码: writer.c reader.c 我的问题是: 由于事先不知道foo和bar将有多少个字节,我如何知道要从reader.c读取多少个字节? 因为例如,如果我在reader中读取10个字节,而foo和bar小于10个字节,那么我会将它们都放在同一个变量中,而这是我不希望的。 理想情况下,我将对每个变量都具有一个读取功能,但是我又一次事先不知道数据将具有多少字节。 我考虑