c++ - 使用 boost::hana 进行自省(introspection)

标签 c++ boost boost-hana

我正在浏览很棒的 boost::hana 库的帮助页面的示例,但无法使内省(introspection)示例正常工作。

这段代码的目的是在编译时检查一个对象是否有一个特定的成员函数,然后使用这个成员函数或者做一些默认的事情。

所以我声明了这两种类型:

struct WithoutToString
{ };

struct WithToString
{
    std::string toString()
    {
        return "implements toString()";
    }
};

这是使用 hana::is_valid 检查的第一个版本:

auto has_toString = hana::is_valid([] (auto&& obj) -> decltype(obj.toString()) { });

template <typename T>
std::string optionalToString1(T const& obj)
{
    return hana::if_(has_toString(obj),
        [] (auto& x) { return x.toString(); },
        [] (auto& x) { return "toString not defined"; }
    )(obj);
}

这是使用 hana::sfinae 检查的第二个版本:

template <typename T>
std::string optionalToString2(T const& obj)
{
    auto maybeToString = hana::sfinae([](auto&& x) -> decltype(x.toString())
    {
        return x.toString();
    });

    return maybeToString(obj).value_or("toString not defined");
}

像这样使用两个版本...

int main()
{
    WithToString obj;

    std::cout << optionalToString1(obj);
    std::cout << optionalToString2(obj);

    return 0;
}

...总是显示“toString not defined”而不是“implements toString()”。

注意:检查objstatic_assert(has_toString(obj), "Does not implement toString().");显示正确的行为。

我错过了什么吗?还是编译器 (clang 5.0.1) 或库 (boost 1.66) 问题?

谢谢。

最佳答案

您的optionalToStringX 函数采用T const&toString 不是 const 限定的成员函数,因此它不适用。

Live On Coliru

#include <boost/hana.hpp>
#include <string>

namespace hana = boost::hana;

struct WithoutToString { }; 
struct WithToString { std::string toString() const { return "implements toString()"; } };

namespace v1 {
    //This is the 1st version of the check using hana::is_valid:
    auto has_toString = hana::is_valid([] (auto&& obj) -> decltype(obj.toString()) { });

    template <typename T>
        std::string optionalToString1(T const& obj)
        {
            return hana::if_(has_toString(obj),
                    [] (auto&& x) { return std::forward<decltype(x)>(x).toString(); },
                    [] (auto&&) { return "toString not defined"; }
                    )(obj);
        }
}

namespace v2 {
    //This is the 2nd version of the check using hana::sfinae:
    template <typename T>
        std::string optionalToString2(T const& obj)
        {
            auto maybeToString = hana::sfinae([](auto&& x) -> decltype(x.toString())
                    {
                    return x.toString();
                    });

            return maybeToString(obj).value_or("toString not defined");
        }
}

#include <iostream>
int main()
{
    WithToString with;
    WithoutToString without;

    std::cout << std::boolalpha << v1::has_toString(without) << std::endl;
    std::cout << std::boolalpha << v1::has_toString(with)    << std::endl;

    std::cout << v1::optionalToString1(without) << std::endl;
    std::cout << v1::optionalToString1(with)    << std::endl;
    std::cout << v2::optionalToString2(without) << std::endl;
    std::cout << v2::optionalToString2(with)    << std::endl;
}

打印

true
false
implements toString()
toString not defined
implements toString()
toString not defined

关于c++ - 使用 boost::hana 进行自省(introspection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49490898/

相关文章:

c++ - 返回模板的模板

python - 找不到 boost 或 python

c++ - 递归编译结构的大小减去填充

c++ - Boost Ublas 矩阵所有元素的平方根

c++ - 使用部分特化从 boost:hana::set 中提取类型失败

c++ - Boost.Hana 测试 lambda 是否可以使用特定参数调用

c++ - 为什么显式运算符 std::string 不起作用

c++ - 使用 Sublime Text 3 构建 C++ 文件

c++ - 我应该如何将 getDC 用作具有自动清理功能的本地对象? C++

c++ - 通过 boost 图将 vector 变量导出到图形