【问题标题】:How to detect explicit cast operator, should is_constructible work?如何检测显式转换运算符,is_constructible 应该工作吗?
【发布时间】:2016-12-11 21:55:05
【问题描述】:

我想检测一个类是否具有显式转换运算符。 我已尝试使用 is_constructible,但以下断言在 msvc 19.00.23506 中失败。

#include <string>
#include <type_traits>

struct Foo { explicit operator std::string() { return ""; } };

static_assert(std::is_constructible<std::string, Foo>::value, "Fail");

我的问题是:

  • is_constructible 应该在这里工作吗?
  • 如何以不同的方式检测它?

【问题讨论】:

标签: c++ c++11 visual-c++ typetraits


【解决方案1】:

is_constructible 应该在这里工作吗?

我认为应该,as there is nothing that excludes explicit conversions。 g++4.8 (及以上) 和 clang++3.6 (及以上) 都能成功编译您的代码。


如何以不同的方式检测它?

您可以尝试使用 detection idiom,它是为 C++17 标准化的,但可在 C++11 中实现(cppreference 页面上提供了符合 C++11 的实现。)

struct Foo { explicit operator std::string() { return ""; } };

template <class T>
using convertible_to_string = decltype(std::string{std::declval<T>()});

// Passes!
static_assert(std::experimental::is_detected<convertible_to_string, Foo>::value, "");

wandbox example

(!) 注意:这种方法在 MSVC 19.10 上似乎无法正常工作(tested here)。这是我使用的full snippet

【讨论】:

  • 如果即使is_constructible 在 MSVC 上也很糟糕,您为什么会期望检测习语(这取决于表达式 SFINAE,它在 MSVC 中的支持已经出了名的糟糕/损坏)起作用?
  • 我不使用 MSVC - 我建议了一种不同的方法,它可能有效,也可能无效。我在this online compiler 上对其进行了测试,它似乎报告了不正确的值。我将编辑答案以明确这一点。
  • 我想在条件模板函数中使用检查,这很好用: typename = decltype(std::string(std::declval())) ,因此接受。 .. 谢谢。
  • @simon 你试过任何“误报”吗? (即当 T 不能转换为字符串时)
  • @Vittorio Romeo 是的,它似乎有效。编译会在函数实现上失败,如果它不起作用,我将模板参数转换为 std::string,但它会抱怨没有适用的重载。
猜你喜欢
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 2011-10-18
  • 2012-01-04
  • 1970-01-01
相关资源
最近更新 更多