我有以下代码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);
我试图让std::vector<std::vector<int>>
类型的vec
强制转换为proxy<std::vector<int>>
。最终我希望foo接受任何容器的容器,但特别是将它们粗略地放入我的类型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
有没有办法达到这个效果?
1条答案
按热度按时间gab6jxml1#
我认为你所需要的就是这个(可能是代替你当前的
foo
实现,它似乎没有任何用处):Live demo
参考OP下面的评论,可以通过修改
ContiguousContainer
概念(现在没有很好的命名)来获得所需的行为,如下所示:Live demo
或者甚至:
合和