【问题标题】:Generic type conversion with template specialization模板特化的泛型类型转换
【发布时间】:2019-11-22 17:17:23
【问题描述】:

我正在努力为类型转换编写一个通用接口。我更愿意通过模板专业化来实现这一点。我的想法是有一个基本模板实现来抛出异常,即在没有专业化可用的情况下。并且用户应该提供所有可能的转换。

我有一个小实现,当然不能正常工作:)

#include <iostream>
#include <functional>

template <typename T, typename F>
T convert(const F & from)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    throw ( std::logic_error("Conversion not implemented!") );
}

template<>
int convert<int, std::string  >( const std::string &  from) {
    return 1;
}

int main() {
    int a;
    std::string b = "hello world";
    const std::string &br = b;
    a = convert<decltype(a), std::remove_reference_t<std::remove_const_t<decltype(br)>> >(br);

    std::cout << a << std::endl;
    return 0;
}

我不明白为什么上面的代码不起作用。我正在从br 中删除 const 和引用,因此它应该调用已实现的专业化,但它不会。我期待您的积极回复,以及是否有更有效的方法来调用转换 API 而无需在模板参数中指定类型。

问候, -阿德南

【问题讨论】:

    标签: c++ templates types c++17 template-meta-programming


    【解决方案1】:

    我正在从 br 中删除 const 和引用

    是的,但顺序错误。

    您在 const 之前和引用之后删除;你应该删除之前的引用和之后的常量

    // ......................................................VVVVVVVVV  reference before
    a = convert<decltype(a), std::remove_const_t<std::remove_reference_t<decltype(br)>> >(br);
    // ..................................^^^^^   const after
    

    重点是decltype(br)就是std::string const &amp;;我的意思是:const 仅适用于 std::string,而不适用于 std::string &amp;

    相反,引用应用于std::string const

    因此,当您将std::remove_const 应用于std::string const &amp; 时,您会再次获得std::string const &amp;,因为完整类型不是const

    接下来你将std::remove_reference 应用到std::string const &amp;,你会得到std::string const

    所以const 仍然存在。

    如果你先使用std::remove_reference,你会从std::string const &amp;得到std::string const

    然后你使用std::remove_const(这一次有效,因为完整类型是const)你得到std::string

    【讨论】:

      【解决方案2】:

      作为补充,在 C++20 中将可以删除带有 std::remove_cvref 的 const 引用,完全结合 std::remove_cvstd::remove_reference

      a = convert<decltype(a), std::remove_cvref_t<decltype(br)>>(br);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-04
        相关资源
        最近更新 更多