如果我的函数
foo
按值而不是通用(转发)引用接受原始类型,我的应用程序会显着加速。但是,如果非基本类型不通过通用引用传递,则加速会丢失。如果 foo
接受固定数量的参数,这就能解决问题:
#include <cstdio>
#include <string>
#include <type_traits>
template <typename T>
requires (!std::is_scalar_v<T>)
auto foo(T&&){
std::puts("pass by universal reference");
}
template <typename T>
requires std::is_scalar_v<T>
auto foo(T){
std::puts("pass by value");
}
int main(){
foo(42); // pass by value
foo(std::string{"hello"}); // pass by universal reference
return 0;
}
但是,问题是
foo
接受模板参数包,并且某些参数可能是原语,而其他参数可能不是。因此,foo
必须首先推导参数类型,然后,如果它们不是基元,则将它们转换为通用引用。如果 foo
是类模板,则可以使用演绎指南来实现:
#include <cstdio>
#include <string>
#include <type_traits>
template <typename T>
using MaybeRef = std::conditional_t<std::is_scalar_v<T>, T, T&&>;
#include <tuple>
template <typename... Ts>
struct Foo {
Foo(MaybeRef<Ts>... args) {
static_assert(std::is_same_v<std::tuple_element_t<0, std::tuple<MaybeRef<Ts>...>>, int>);
static_assert(std::is_same_v<std::tuple_element_t<1, std::tuple<MaybeRef<Ts>...>>, std::string&>);
std::puts("passed");
}
};
template <typename... Ts>
Foo(Ts&&...) -> Foo<MaybeRef<Ts>...>;
int main(){
std::string str = "hello";
Foo{42, str};
return 0;
}
但是,我不知道如何为我的功能实现相同的功能
foo
。
这可能吗?如何实现?