简短版:
如果我有这样的功能:
constexpr bool has_some_property(Foo) { return true; }
有没有什么方法可以调用函数而不必实际实例化 Foo
?假设 Foo
不是默认可构造的吗?
冗长的版本:
安东尼·威廉姆斯最近 wrote an article详细介绍了为任何 enum class
启用的一组免费功能专门化特定模板的对象。它遵循 <ios>
中的类似方案。 , std::is_error_code
,其中专门针对用户定义的类型或值的模板以允许 enable_if
启用某些功能。以安东尼为例:
template<>
struct enable_bitmask_operators<my_bitmask>{
static constexpr bool enable=true;
};
然后在定义运算符时:
template<typename E>
typename std::enable_if<enable_bitmask_operators<E>::enable,E>::type
operator|(E lhs,E rhs){
此技术的问题是模板特化必须与原始模板位于相同的命名空间中,因此这是行不通的:
namespace mystuff {
enum class Foo {
...
};
// Fail: wrong namespace
template<>
struct enable_bitmask_operators<Foo> : std::true_type {}
另一种方法是使用 constexpr
函数,可以在与类相同的命名空间中解析:
namespace mystuff {
enum class Foo {
...
};
constexpr bool enable_bitmask_operators(Foo) { return true; }
然后在定义处:
template<typename E>
typename std::enable_if<enable_bitmask_operators(E()),E>::type
operator|(E lhs,E rhs){
这样做的好处是即使在嵌套类中也能很好地工作。它的问题是它需要一个默认的可构造类。这适用于我们的 enum class
例如,但它不能作为特化问题的通用解决方案。因此,如果我们想象尝试使用 constexpr
函数而不是其他类的模板特化我们可能会遇到其他失败:
struct Foo {
Foo() = delete;
};
constexpr bool has_some_property(Foo) { return true; }
...
// Fail for Foo...use of deleted function
template<typename E>
typename std::enable_if<has_some_property(E()),E>::type doStuff() {}
这有点令人沮丧,因为我实际上并不需要创建该对象,我只是希望它在那里供 ADL 识别 constexpr
函数来调用。我一直在想应该有某种方式可以说我想要那个功能而不必实际创建对象。我玩过std::declval
但这在这种情况下不起作用。
有人知道解决这个难题的方法吗?
最佳答案
只是不要使用constexpr
:
std::true_type has_some_property(Foo&& );
Foo
有吗?
using has_it = decltype(has_some_property(std::declval<Foo>()));
static_assert(has_it::value, "It should!");
这是一个未计算的上下文,所以我们永远不必调用任何 Foo
构造函数。并且可以回避 constexpr
需要常量表达式的问题。
关于c++ - 在不创建参数对象的情况下解析 constexpr 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28423742/