具有模板专业化的通用类型转换
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_cv
和 std::remove_reference
:
a = convert<decltype(a), std::remove_cvref_t<decltype(br)>>(br);
我正在努力编写一个用于类型转换的通用接口。我更愿意通过模板专业化来实现这一点。我的想法是有一个基本模板实现来抛出异常,即万一没有可用的专业化。并且用户应该提供所有可能的转换。
我有一个小的实现,当然不能用 :)
#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_cv
和 std::remove_reference
:
a = convert<decltype(a), std::remove_cvref_t<decltype(br)>>(br);