我是模板的新手,特別是引數包,我想知道我是否可以從包中獲取第一個值。
例如下面的代碼:
template <typename T, typename... Args>
bool register(Args... args) {
if (!Foo<T>(args..) {
assert(std::is_same_v<std::string, args...[0]>);
std::cerr << "Failed call Foo with " args...[0] "\n";
}
}
我如何真正獲得第一個值args...?
值得一提的是args..。可以包含不同的型別(字串、布林值等)
uj5u.com熱心網友回復:
在您的情況下更簡單似乎將您的功能更改為:
template <typename T, typename Arg, typename... Args>
bool register(Arg arg, Args... args) {
if (!Foo<T>(arg, args...) {
assert(std::is_same_v<std::string, Arg>);
std::cerr << "Failed call Foo with " arg "\n";
}
}
從斷言中,即使
template <typename T, typename... Args>
bool register(const std::string& s, Args... args) {
if (!Foo<T>(s, args...) {
std::cerr << "Failed call Foo with " s "\n";
}
}
else<tuple>提供了一些有用的工具:
template <typename T, typename Arg, typename... Args>
bool register(Args... args) {
if (!Foo<T>(args...) {
assert(std::is_same_v<std::string,
std::tuple_element_t<0, std::tuple<Args...>>);
std::cerr << "Failed call Foo with "
std::get<0>(std::tie(args...)) "\n";
}
}
uj5u.com熱心網友回復:
您可以使用 lambda 來提取第一個引數:
template<typename T, typename... Args>
bool register(Args... args) {
if (!Foo<T>(args...)) {
auto& first = [](auto& first, ...) -> auto& { return first; }(args...);
static_assert(std::is_same_v<std::string,
std::remove_reference_t<decltype(first)>>);
std::cerr << "Failed call Foo with " first "\n";
}
}
uj5u.com熱心網友回復:
我通常使用上述解決方案,只需為第一個引數添加一個顯式的額外模板引數。如果你不能這樣做,這也有效:
#include <type_traits>
namespace details
{
template<typename type_t, typename... args_t>
struct deduce_first
{
using type = type_t;
};
}
template<typename... args_t>
using first_t = typename details::deduce_first<args_t...>::type;
template<typename... args_t>
bool register_f(args_t&&... args)
{
static_assert(std::is_same_v<first_t<args_t...>, bool>, "first argument should have type bool");
return true;
}
int main()
{
register_f(true, 1.0);
// register_f(1.0); <== does indeed not complie
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/371190.html
上一篇:typename之前的模板值
