我目前正在为元组编写算术运算符重载.运算符迭代元组以对其每个元素执行操作.这是operator + =的定义:
template< typename... Ts, std::size_t I = 0 >
inline typename std::enable_if< I == sizeof... (Ts), std::tuple< Ts... >& >::type operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
return lhs;
}
template< typename... Ts, std::size_t I = 0 >
inline typename std::enable_if< I != sizeof... (Ts), std::tuple< Ts... >& >::type operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
std::get< I >(lhs) += std::get< I >(rhs);
return operator +=< Ts..., I + 1 …Run Code Online (Sandbox Code Playgroud) 给定一个C符合STL的容器类型,如何正确检测是否C包含成员函数reserve?我尝试了以下方法(使用GCC 4.6.3):
template< typename C, typename = void >
struct has_reserve
: std::false_type
{};
template< typename C >
struct has_reserve< C, typename std::enable_if<
std::is_same<
decltype( &C::reserve ),
void (C::*)( typename C::size_type )
>::value
>::type >
: std::true_type
{};
Run Code Online (Sandbox Code Playgroud)
这适用于C存在std::vector,但不适用于无序容器,例如std::unordered_set.其原因是,这reserve是一个的(直接)成员函数std::vector,但是对于无序的容器它是从基类继承的,即,它的签名是不void (C::*)( typename C::size_type )但void (B::*)( typename C::size_type )对于一些未指定的基类B的C.
我知道如何解决它并检测reserve即使是遗传,但它看起来很笨拙,我想知道标准允许什么.所以...
我的问题是:标准是允许reserve从未指定的基类继承还是概要绑定并需要直接成员函数?
如果用户将函数指针作为参数传递,我想使用SFINAE来启用特定模板.
我用谷歌搜索但没有发现任何东西 - 我也尝试查看<type_traits>文档,但找不到任何类似的东西is_function_ptr<T>.
通过函数指针,我的意思是全局函数指针,比如TReturn(*)(TArgs...).
是否有一种技术/最佳风格可以为某些类型分组类模板特化?
一个例子:假设我有一个类模板Foo,我需要为排版设置相同的专用模板
A = { Line, Ray }
Run Code Online (Sandbox Code Playgroud)
而另一种方式是排版B.
B = { Linestring, Curve }
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include <type_traits>
using namespace std;
// 1st group
struct Line {};
struct Ray {};
// 2nd group
struct Curve {};
struct Linestring {};
template<typename T, typename Groupper=void>
struct Foo
{ enum { val = 0 }; };
// specialization for the 1st group
template<typename T>
struct Foo<T, typename enable_if<
is_same<T, Line>::value ||
is_same<T, Ray>::value
>::type>
{ …Run Code Online (Sandbox Code Playgroud) 我已经知道你可以启用(或不启用)类的方法 std::enable_if
举个例子:
template<size_t D, size_t E>
class Field
{
...
size_t offset(const std::array<float,D>& p) const
{
...
}
template<typename TT = size_t>
typename std::enable_if<D!=E, TT>::type
offset(const std::array<float,E>& p) const
{
return offset(_projection(p));
}
...
};
Run Code Online (Sandbox Code Playgroud)
这有助于无法调用在特定情况下无效的函数以及删除重载错误......对我而言,这非常好!
我想进一步让我的班级成员只在需要时出席.这样,如果我尝试使用一个原本不会被启动的异议,我会收到错误
我试着这样做
template<size_t D, size_t E>
class Field
{
...
template<typename TT = projectionFunc>
typename std::enable_if<D!=E, TT>::type _projection;
}
Run Code Online (Sandbox Code Playgroud)
但是编译器告诉我:
erreur: data member ‘_projection’ cannot be a member template
Run Code Online (Sandbox Code Playgroud)
有没有办法实现我想要的?
在cppreference的语言参考中std::enable_if包括以下注释
笔记
一个常见的错误是声明两个仅在默认模板参数上有所不同的函数模板.这是非法的,因为默认模板参数不是函数模板签名的一部分,并且声明具有相同签名的两个不同函数模板是非法的.
在下面的示例中的模板函数中,在我看来,这种情况发生.即,两个模板函数onlyForDerivedObjects(...)似乎(对我来说)仅由它们的默认模板参数不同.我意识到我在这里遗漏了一些东西,希望有人可以向我解释这一点,或者指出我可能会为自己找到顿悟的方向.
typename std::enable_if ...当我认为它产生两个模板函数的情况时,我在下面的模板函数中错误分类了部分,这两个模板函数的区别仅在于它们的默认模板参数?基础和派生类:
class BaseA
{
public:
int getInt() const { return 21; };
};
class DerivedA : public BaseA {};
class BaseB
{
public:
int getAnotherInt() const { return 33; };
};
class DerivedB : public BaseB {};
Run Code Online (Sandbox Code Playgroud)
具有以下模板功能
/* template functions that, seemingly, only differ in their
default template arguments? */
template< class T,
typename std::enable_if<std::is_base_of<BaseA, …Run Code Online (Sandbox Code Playgroud) 我目前正在与Visual Studio 2017进行斗争(/std:c++latest如果有任何帮助,请编译使用).
有问题的代码只是根据一些模板化constexpr函数的结果选择结构特化.GCC和clang编译它没有问题.
这是我的MCVE:
#include <type_traits>
struct A {
enum {
test_trait = true
};
};
template<typename T>
constexpr int choose() {
return T::test_trait;
}
template<typename T, typename Enable=void>
struct Chosen;
template<typename T>
struct Chosen<T, std::enable_if_t<choose<T>() == 1>> {};
void foo() {
// This works
constexpr int chosen = choose<A>();
static_assert(chosen == 1, "");
// This resolves to the undefined struct.
using Chosen_t = Chosen<A>;
Chosen_t x;
(void)x;
}
Run Code Online (Sandbox Code Playgroud)
choose()在我的代码库中实际上有点复杂,但static_assert仍然编译,并检查正常.
我有点假设,如果static_assert …
如果我有一个包装标准容器的模板,似乎我可以合理地轻松委托initializer_list构造函数:
template<typename T>
struct holder {
T t_;
holder() :
t_() {}
holder(std::initializer_list<typename T::value_type> values)
: t_(values) {}
};
Run Code Online (Sandbox Code Playgroud)
因此,这与std :: vector很好地配合.
int main(int argc, char* argv[]) {
holder<std::vector<int>> y{1,2,3};
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
但它很明显不适用于T作为'int',或任何其他没有嵌套value_type typedef的类型.所以,我想使用某种enable_if或类似技巧来使initializer_list构造函数不被发出,除非T都定义了嵌套的value_type typedef,并且可以从std :: initializer_list构造.
我尝试了下面这个,但它仍然不起作用,因为编译器(在我的情况下是clang ++ 3.1),当T为int时仍会跳过无效的T :: value_type:
holder(typename std::enable_if<std::is_constructible<T, std::initializer_list<typename T::value_type>>::value, std::initializer_list<typename T::value_type>>::type values)
: t_(values) {}
Run Code Online (Sandbox Code Playgroud)
关于如何表达概念的任何想法"在T的value_type上给这个模板提供初始化列表构造函数,当且仅当T具有value_type typedef且可从T :: value_type的initializer_list构造时".
给定一个数组a,我想countof(a)将数组中的元素数作为编译时常量.如果我有一个指针p,我想countof(p)不编译.这似乎应该是(1)直截了当,(2)通常涵盖在SO中,但(1)我无法使它工作,并且(2)搜索SO没有发现任何东西.
这是我的尝试.
#include <cstddef>
#include <type_traits>
template<typename T, std::size_t n,
typename = typename std::enable_if<std::is_array<T>::value>::type>
constexpr std::size_t countof(T (&)[n]) { return n; }
template<typename T,
typename = typename std::enable_if<std::is_pointer<T>::value>::type>
void countof(T*) = delete;
int main()
{
int a[10];
auto asize = countof(a); // should compile
static_assert(countof(a) == 10,
"countof(a) != 10!");
int *p;
auto psize = countof(p); // shouldn't compile
}
Run Code Online (Sandbox Code Playgroud)
救命?
我试图在显式和隐式转换构造函数之间切换enable_if.
我的代码目前看起来像
#include <type_traits>
#include <cstdint>
enum class enabled {};
template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type;
template <bool B, typename T = void> using disable_if_t = typename std::enable_if<!B, T>::type;
template <std::intmax_t A> struct SStruct
{
static constexpr std::intmax_t a = A;
};
template <typename T> struct SCheckEnable : std::integral_constant<bool, T::a == 0>
{
};
template <typename U, typename T> class CClass
{
public:
template <typename T2, enable_if_t<SCheckEnable<U>::value, enabled>...> constexpr CClass(T2 v) …Run Code Online (Sandbox Code Playgroud)