我有以下代码godbolt链接:
#include <iostream>
#include <array>
#include <vector>
#include <span>
#include <cstdint>
#include <string>
template <typename T>
constexpr auto type_name() {
std::string_view name, prefix, suffix;
#ifdef __clang__
name = __PRETTY_FUNCTION__;
prefix = "auto type_name() [T = ";
suffix = "]";
#elif defined(__GNUC__)
name = __PRETTY_FUNCTION__;
prefix = "constexpr auto type_name() [with T = ";
suffix = "]";
#elif defined(_MSC_VER)
name = __FUNCSIG__;
prefix = "auto __cdecl type_name<";
suffix = ">(void)";
#endif
name.remove_prefix(prefix.size());
name.remove_suffix(suffix.size());
return name;
}
template <typename T>
concept ContiguousContainer = requires (T t) {
t.data();
t.size();
};
template<typename T>
struct proxy{
template<typename V>
proxy( const V & v ) noexcept
: m_size( v.size() )
, m_ptr( v.data() )
{}
std::size_t m_size;
const T* m_ptr;
};
template<typename V>
proxy(const V &v) noexcept -> proxy<typename V::value_type>;
template<ContiguousContainer T>
int foo(const proxy<T>& temp){
return 1;
}
int main(){
std::vector<std::vector<int>> vec;
auto temp_0 = foo<decltype(vec)::value_type>(vec);
auto temp_1 = proxy(vec); //works as intended
std::cout << type_name<decltype(temp_1)>() << std::endl;
auto temp_2 = foo(vec); //doesn't compile.
return 0;
}
我想做的是得到最后一行
auto temp_2 = foo(vec);
上班。我正在尝试让
vec
类型的 std::vector<std::vector<int>>
强制转换为函数中的 proxy<std::vector<int>>
。最终,我希望 foo 接受任何 container of containers,但特别将它们粗略化为我的类型,proxy
,这在我的实际代码中还有其他好处(可以采用单个值和初始化列表,因此我想要它进入那种)。现在我可以在没有模板的情况下,简单地使用构造函数来转换 (temp_1),但我不能用函数这样做。我想要一个函数,可以将任何容器(以.data()
和.size()
为成员)作为参数并自动将其转换为proxy
类型。但是我收到以下错误:
x86-64 gcc 13.1
x86-64 gcc 13.1
-std=c++20
123
<Compilation failed>
# For more information see the output window
x86-64 gcc 13.1 - 1753ms
<source>: In function 'int main()':
<source>:61:22: error: no matching function for call to 'foo(std::vector<std::vector<int> >&)'
61 | auto temp_2 = foo(vec); //doesn't compile.
| ~~~^~~~~
<source>:51:5: note: candidate: 'template<class T> requires ContiguousContainer<T> int foo(const proxy<T>&)'
51 | int foo(const proxy<T>& temp){
| ^~~
<source>:51:5: note: template argument deduction/substitution failed:
<source>:61:22: note: 'std::vector<std::vector<int> >' is not derived from 'const proxy<T>'
61 | auto temp_2 = foo(vec); //doesn't compile.
| ~~~^~~~~
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:61:22: error: no matching function for call to 'foo(std::vector<std::vector<int> >&)'
61 | auto temp_2 = foo(vec); //doesn't compile.
| ~~~^~~~~
<source>:51:5: note: candidate: 'template<class T> requires ContiguousContainer<T> int foo(const proxy<T>&)'
51 | int foo(const proxy<T>& temp){
| ^~~
<source>:51:5: note: template argument deduction/substitution failed:
<source>:61:22: note: 'std::vector<std::vector<int> >' is not derived from 'const proxy<T>'
61 | auto temp_2 = foo(vec); //doesn't compile.
| ~~~^~~~~
Execution build compiler returned: 1
我有办法达到这个效果吗?
我认为您所需要的就是这个(可能代替您当前实施的
foo
,这似乎毫无用处):
template<typename T> requires ContiguousContainer <T>
auto foo(const T& temp){
return proxy (temp);
}
参考OP在下面的评论,可以通过修改
ContiguousContainer
概念(现在没有很好地命名)来获得所需的行为,如下所示:
template <typename T>
concept ContiguousContainer = requires (T t) {
t.data();
t.size();
t.data ()->data ();
t.data ()->size ();
};
甚至:
template <typename T>
concept ContiguousContainer = requires (T t) {
t.data ()->data ();
t.data ()->size ();
};
呵呵