我正在努力编写一个用于类型转换的通用接口。我希望通过模板专门化来实现。我的想法是要有一个基本的模板实现来引发异常,即在没有专门化的情况下。用户应该提供所有可能的转换。
我有一个很小的实现,它当然是行不通的:)
#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
答案 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_cv
和std::remove_reference
删除std::remove_cvref
的const引用:
a = convert<decltype(a), std::remove_cvref_t<decltype(br)>>(br);