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

时间:2019-11-22 17:17:23

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

我正在努力编写一个用于类型转换的通用接口。我希望通过模板专门化来实现。我的想法是要有一个基本的模板实现来引发异常,即在没有专门化的情况下。用户应该提供所有可能的转换。

我有一个很小的实现,它当然是行不通的:)

#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和reference,所以它应该调用已实现的专业化,但不是。我期待您的积极答复,也希望有一种更有效的方法来调用convert API,而无需在模板参数中指定类型。

关于, -Adnan

2 个答案:

答案 0 :(得分:5)

  

我要从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 &;我的意思是: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

答案 1 :(得分:0)

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

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