编辑 3:
我会把我的旧帖子留给任何有兴趣的人。但是,我刚刚找到了明显的解决方案......
#include <user_span>
//dive into your namespace to avoid name collisions
namespace YOUR_LIB
{
//supply custom type
template <class T, SIZET size = DEFAULT>
using span = ::user_span<T, size>;
}
//actually include the library
#include <your_lib>
使用这种方法,您可以在任何地方使用 span 并像往常一样编程。
原来的:
一种解决方案是使用具有默认值的跨度模板。喜欢:
template <template<class,size_t> class Span>
void read_data(Span<float> data);
但是,您可能会遇到为容器使用不同签名的各种库的问题。因此,更好的方法是:
template <class Span>
void read_data(Span data);
您现在缺少值的类型,但您应该能够通过以下方式检索它:
using T = typename Span::value_type
此外,您可能希望向std::enable_if
您的函数添加一些(或概念),以检查是否Span
确实提供了您正在使用的成员函数。
在实践中,以上所有可能导致非常嘈杂的代码。如果您只有一个简单的案例,更简单的方法可能是使用using
库用户的声明来定义 span。
以上可能不适用于std::vector
重载,因为类型签名有些相似。您可以通过提供显式std::vector
重载来解决此问题,这些重载执行正确的强制转换并调用Span
版本。
编辑:
从您的评论中,我了解到您想将未指定的类型(任何容器)转换为未指定的类型(任何跨度)。这既不合理也不可能。您将需要在某处定义其中一种类型。
话虽如此,您可以编写与转换无关的代码并让用户提供实际的转换。喜欢:
template <class Span>
void read_data_impl(Span data);
template <class Container>
void read_data(Container data)
{
read_data_impl(convert(data));
}
然后用户需要提供:
template <class Container>
auto convert(Container& data)
{
return USERSPAN(data);
}
编辑2:
我的代码中有一个错误。convert 函数中的data
必须通过引用传递。此外,如果您通过 allowT
手动传递容器值可能会有所帮助。因此,您最终得到:
template <class Span>
void read_data_impl(Span data);
template <class Container>
void read_data(Container data)
{
read_data_impl(convert(data));
}
template <class T, class Container>
void read_data(Container data)
{
read_data_impl(convert<T>(data));
}
对于转换:
template <class T, class Container>
auto convert(Container& data)
{
return convert_impl<T>(data);
}
template <class Container>
auto convert(Container& data)
{
return convert_impl<typename Container::value_type>(data);
}
然后用户必须提供以下功能:
template <class T, class Container>
auto convert_impl(Container& data)
{
return USERSPAN<T>(data);
}