我有一个template <class Class>
泛型函数,包括:
std::ostringsteam objectStream;
objectStream << std::forward<Class>(object);
return objectStream.str();
为了提高效率,我希望优化Class
字符串的大小写。
因此,我正在对模板进行标签分发,以使Scott Myers的《 Effective Modern C ++》一书中每项27的模板功能超载。
因此,我需要在编译时生成std::true_type
或std::false_type
。
鉴于template<class Class>
,如果以下任何表达式为真,我就需要std::true_type
:
std::is_same<typename std::decay<Class>::type, char * >()
std::is_same<typename std::decay<Class>::type, const char * >()
std::is_same<typename std::decay<Class>::type, string >()
std::is_same<typename std::decay<Class>::type, string * >()
std::is_same<typename std::decay<Class>::type, const string * >()
我不确定如何执行“或”操作,以便编译器可以在编译时正确分派标签。
相关问题,是否可以将const
放到const char *
中以使其成为char *
?
答案 0 :(得分:2)
因此,我需要在编译时生成
/module/
或widget.auth.isMyuser(_userId).then((val) { setState(() { if (val != null) { _isMyuser = val; } }); });
。鉴于
std::true_type
,如果其中任何一个表达式为真,我就需要std::false_type
[...]
记住template<class Class>
和std::true_type
分别是
std::true_type
如果我理解正确,您想要这个或类似的东西
std::false_type
相关问题,是否可以将
std::integral_constant<bool, true>; // aka std::true_type std::integral_constant<bool, false>; // aka std::false_type
放到using tct = typename std::decay<Class>::type; // to make shorter using yourType = std::integral_constant<bool, std::is_same<tct, char * >::value || std::is_same<tct, const char * >::value || std::is_same<tct, string >::value || std::is_same<tct, string *>::value || std::is_same<tct, const string *>::value>;
中以使其成为const
?
我想您可以按照以下步骤创建自定义模板
const char *
因此您可以按如下方式简化前面的代码
char *
答案 1 :(得分:2)
第一个问题,
如果您使用的是c ++ 17,则可以使用fold表达式在几行中完成
#include <iostream>
using namespace std;
template <typename C, typename... Ts>
using matches_my_types = std::bool_constant< ( ... | std::is_same<C,Ts>::value)>;
//or with a predefined set of types..
template <typename C>
using matches_my_predefined_set_of_types = matches_my_types<C,bool,double,int>;
int main() {
using Class = int;
std::cout << matches_my_types<Class,bool,double,int>::value << std::endl;
std::cout << matches_my_predefined_set_of_types<Class>::value << std::endl;
return 0;
}
对于c ++ 11,您可以执行类似的操作,但是使用递归代替折叠。
#include <iostream>
using namespace std;
template<typename B, typename...Bs> struct any_true
: std::conditional_t<bool(B::value), B, any_true<Bs...>>{};
template<typename B> struct any_true<B> : B {};
template <typename C, typename... Ts>
using matches_my_types = any_true<std::is_same<C,Ts>...>;
int main() {
using Class = int;
std::cout << matches_my_types<Class,bool,double,int>::value << std::endl;
return 0;
}
对于第二个问题,如果要在指向const T的指针上常规删除const,则可以使用内置的type_traits和有条件的
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
using remove_const_if_pointer_to_const =
std::conditional_t<std::is_pointer<T>::value,
std::add_pointer_t<std::remove_const_t<std::remove_pointer_t<T>>>,
T>;
int main() {
using A = int;
using B = int*;
using C = const int*;
std::cout << typeid(remove_const_if_pointer_to_const<A>).name() << std::endl;
std::cout << typeid(remove_const_if_pointer_to_const<B>).name() << std::endl;
std::cout << typeid(remove_const_if_pointer_to_const<C>).name() << std::endl;
return 0;
}
答案 2 :(得分:0)
我喜欢max66的答案。简单而优雅。
如果您需要更经典的元函数解决方案(例如check_type_t<T>
之类的东西,并且您不想使用任何boost::mpl
或boost::hana
之类的元编程库...您可以简单地执行以下操作:
template <class Class, class = void>
struct check_type_ {
using type = std::false_type;
};
template <class Class>
struct check_type_<Class,
std::enable_if_t<
std::is_same<typename std::decay<std::remove_const_t<Class>>::type, char*>::value
>> {
using type = std::true_type;
};
template <class Class>
struct check_type_<Class,
std::enable_if_t<
std::is_same<typename std::decay<std::remove_const_t<Class>>::type, string*>::value
>> {
using type = std::true_type;
};
template <class Class>
struct check_type_<Class,
std::enable_if_t<
std::is_same<typename std::decay<Class>::type, string>::value
>> {
using type = std::true_type;
};
template <class Class>
using check_type_t = typename check_type_<Class>::type;
static_assert(std::is_same<check_type_t<char*>, std::true_type>::value, "");
static_assert(!std::is_same<check_type_t<int>, std::true_type>::value, "");
C ++会尝试选择最专业的模板,以便在Class
中将所需的任何类型(例如字符串)传递给check_type_t<>
时,
std::enable_if_t<
std::is_same<typename std::decay<Class>::type, string>::value
>
格式不正确,导致void
。因此,选择了该专业化,内部类型为std::true_type
。如果没有一个专业分工良好,则选择主模板,结果为std::false_type
。
我希望它能帮上忙。