具有模板专业化的通用类型转换

Generic type conversion with template specialization

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

我有一个小的实现,当然不能用 :)

#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 而无需在模板参数中指定类型。

此致, -阿德南

I am removing const and reference from the br

是的,但顺序错误。

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

之前删除 reference before 和 const after

// ......................................................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 &;我的意思是:const 仅适用于 std::string,不适用于 std::string &

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

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

接下来,您将 std::remove_reference 应用于 std::string const &,您将得到 std::string const

因此 const 仍然存在。

如果您先使用 std::remove_reference,则从 std::string const & 获得 std::string const

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

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

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