简化模板接口,删除冗余类型
#include <cstddef>
#include <utility>
template <size_t N, typename... V>
struct T {
int test(size_t n, const char** ss) {
if (N > n)
return 1;
return []<size_t... I>(const char* ss[N], std::index_sequence<I...>) {
return test_impl(ss[I]...);
}(ss, std::make_index_sequence<N>{});
}
// Ideally this would be templated, solving my problem:
// i.e. move "typename... V" from the struct to this function.
virtual int test_impl(V...) = 0;
};
template <typename U, size_t N, typename... V>
struct T1 : T<N, V...> {
U value;
int (*tester)(U*, V...);
int test_impl(V... v) {
return tester(&value, v...);
}
// virtual is not an aggregate
T1(U value, int (*tester)(U*, V...))
: value{value}, tester{tester}
{};
};
int test1(int* v, const char* s1, const char* s2) {
return 1;
}
template <typename... V>
int test2(int* v, V... ss) {
return 1;
}
C ++非常擅长从函数参数推导模板功能参数,但是不允许虚拟函数模板。我被迫将函数模板参数移至结构模板,并发现C ++不擅长从成员变量推导模板结构参数。最后,我被迫将冗余信息指定为模板,该信息使t1
/t
接口难以使用?我该如何解决?
例如,在这里我们知道:
sizeof ...(v)== n
exttype(v)
必须是const char*
- template参数
u
可以仅从t1
构造 - 函数模板参数
v ...
的参数中得出。 > t1 构造器 - 遵循该模板参数
n
可以仅从t1
构造函数的参数中得出。
int main() {
// The '2' and the 'const char*'... are redundant
T1 a = T1<int, 2, const char*, const char*>(10, test1);
T1 b = T1<int, 2, const char*, const char*>(10, test2);
// There is enough information here to deduce the values
T1 c = T1(10, test1);
// There is enough information here to deduce the values
T1 d = T1<..., 2, ...>(10, test2);
}
#include <cstddef>
#include <utility>
template <size_t N, typename... V>
struct T {
int test(size_t n, const char** ss) {
if (N > n)
return 1;
return []<size_t... I>(const char* ss[N], std::index_sequence<I...>) {
return test_impl(ss[I]...);
}(ss, std::make_index_sequence<N>{});
}
// Ideally this would be templated, solving my problem:
// i.e. move "typename... V" from the struct to this function.
virtual int test_impl(V...) = 0;
};
template <typename U, size_t N, typename... V>
struct T1 : T<N, V...> {
U value;
int (*tester)(U*, V...);
int test_impl(V... v) {
return tester(&value, v...);
}
// virtual is not an aggregate
T1(U value, int (*tester)(U*, V...))
: value{value}, tester{tester}
{};
};
int test1(int* v, const char* s1, const char* s2) {
return 1;
}
template <typename... V>
int test2(int* v, V... ss) {
return 1;
}
C++ is very good at deducing template function parameters from function arguments, but virtual function templates are not allowed. I am forced to move the function template parameters to the struct template, and find that C++ is not good at deducing template struct parameters from member variables. In the end I am forced to specify redundant information to the template which makes the T1
/T
interface difficult to use? How can I fix this?
For example, here we know that:
sizeof...(V) == N
decltype(V)
must beconst char*
- template parameter
U
can be deduced solely from the argument of theT1
constructor - template parameter
V...
can be deduced solely from the argument of theT1
constructor - from which it follows that template parameter
N
can be deduced solely from the argument of theT1
constructor.
int main() {
// The '2' and the 'const char*'... are redundant
T1 a = T1<int, 2, const char*, const char*>(10, test1);
T1 b = T1<int, 2, const char*, const char*>(10, test2);
// There is enough information here to deduce the values
T1 c = T1(10, test1);
// There is enough information here to deduce the values
T1 d = T1<..., 2, ...>(10, test2);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
no,编译器不知道。 (查看错误消息),
由于您有此先决条件,因此您不必拥有模板参数
n
。参见在线演示
No, the compiler doesn't know it. (Take a look at the error messages)
Since you have this prequisite, you don't have to have the template parameter
N
.See online demo