我正在创建一个非常小的C++项目,我想根据自己的需要创建一个简单的矢量类.该std::vector模板类不会做.当向量类由chars(即vector<char>)组成时,我希望它能够与a进行比较std::string.经过一番乱搞之后,我编写的代码既可以编译也可以执行我想要的操作.见下文:
#include <string>
#include <stdlib.h>
#include <string.h>
template <typename ElementType>
class WorkingSimpleVector {
public:
const ElementType * elements_;
size_t count_;
// ...
template <typename ET = ElementType>
inline typename std::enable_if<std::is_same<ET, char>::value && std::is_same<ElementType, char>::value, bool>::type
operator==(const std::string & other) const {
if (count_ == other.length())
{
return memcmp(elements_, other.c_str(), other.length()) == 0;
}
return false;
}
};
template <typename ElementType>
class NotWorkingSimpleVector {
public:
const ElementType * elements_;
size_t count_;
// ... …Run Code Online (Sandbox Code Playgroud) 我正在使用这个答案的样式SFINAE,以便通过使用适当的成员函数调用泛型矢量对象.例如,以下代码operator[](int) const首先调用,如果不存在,则operator()(int) const:
template<int I> struct rank : rank<I-1> { static_assert(I > 0, ""); };
template<> struct rank<0> {};
template<typename VectorType>
struct VectorWrapper
{
auto get(int i) const
{
return get(v, i, rank<5>());
}
template<typename V, typename = std::enable_if_t<has_bracket_operator<const V>::value> >
auto get(V const& v, int i, rank<2>) const
{
return v[i];
}
template<typename V, typename = std::enable_if_t<has_parenthesis_operator<const V>::value> >
auto get(V const& v, int i, rank<1>) const
{
return v(i);
}
VectorType v; …Run Code Online (Sandbox Code Playgroud) 有没有办法编译方法,取决于模板参数?我正在尝试创建一个可以处理2,3或更多维度的Coordinate类.我想提供access方法as x(),y()和z(),但我希望z()方法只有在尺寸大于3时才可访问.现在(如下所示),我使用a static_assert来防止使用z()尺寸2的坐标.
template<typename DataType, int Dimension>
class Coord
{
private:
std::array<DataType, Dimension> _data;
public:
// how to achieve some kind of compile_if()
DataType& z()
{
static_assert(Dimension >= 3, "Trying to access an undefined dimension.");
return _data[2];
}
};
Run Code Online (Sandbox Code Playgroud)
我想要做的是隐藏z()维度2的存在,以便这样做
Coord<int, 2> ci2(0,0);
ci2.z() = 3; // shouldn't compile
Run Code Online (Sandbox Code Playgroud)
不使用static_assert就不编译.我见过很多关于std :: enable_if的问题,但据我所知,它是用来启用或禁用特定的重载.
问题是:是否有办法根据编译时参数使方法可用或不可用?
基本上我希望我的范围类型可以隐式转换Range<const char>为Range<const unsigned char>.std :: enable_if似乎不可能,因为该函数不带参数且没有返回.是什么工作?
这基本上是我尝试过的:
template<typename T>
class Range{
T* begin_;
T* end_;
public:
Range(T* begin,T* end):begin_{begin},end_{end}{}
template<int N>
Range(T (&a)[N]):begin_{static_cast<T*>(&a[0])},end_{static_cast<T*>(&a[N-1])}{}
T* Begin(){return begin_;}
T* End(){return end_;}
operator typename std::enable_if<std::is_same<T,const char>::value,Range<const unsigned char>&>::Type (){
return *reinterpret_cast<Range<const unsigned char>*>(this);
}
};
Run Code Online (Sandbox Code Playgroud) 我有一个模板类,其类型是迭代器.我想根据模板参数的iterator_category启用/禁用特定成员函数.特别是,operator--如果模板参数是双向迭代器,我想启用.我的尝试是这样的:
typename std::enable_if<
std::is_base_of<std::bidirectional_iterator_tag,
MyTemplateParameter>::value,
MyType&>::type
operator --() {
//do work
return *this;
}
Run Code Online (Sandbox Code Playgroud)
Clang告诉我(粗略地): error: no type named 'type' in 'std::__1::enable_if<false, MyTemplateParameter>'; 'enable_if' cannot be used to disable this declaration
有没有办法完成我正在尝试的东西?
以下是某些上下文中的示例:
#include <iterator>
#include <type_traits>
template <typename TagType>
class test {
public:
typename std::enable_if<
std::is_base_of<std::bidirectional_iterator_tag,
TagType>::value,
test>::type
operator --() {
return *this;
}
};
int main(){
test<std::random_access_iterator_tag> t1;
test<std::forward_iterator_tag> t2;
/*
breakTemps.cpp:13:2: error: no type named 'type' in 'std::__1::enable_if<false, test<std::__1::forward_iterator_tag> >'; 'enable_if' cannot be used to …Run Code Online (Sandbox Code Playgroud) 为什么这个代码(M类中的fnc值)不能通过SFINAE规则解决?我收到一个错误:
Error 1 error C2039: 'type' : is not a member of
'std::tr1::enable_if<_Test,_Type>'
Run Code Online (Sandbox Code Playgroud)
当然类型不是成员,它没有在enable_if的这个通用版本中定义,但是如果bool为真,并且如果它是假的则不实例化那么这不是fnc的这个版本背后的全部想法吗?可以请有人向我解释一下吗?
#include <iostream>
#include <type_traits>
using namespace std;
template <class Ex> struct Null;
template <class Ex> struct Throw;
template <template <class> class Policy> struct IsThrow;
template <> struct IsThrow<Null> {
enum {value = 0};
};
template <> struct IsThrow<Throw> {
enum {value = 1};
};
template <template <class> class Derived>
struct PolicyBase {
enum {value = IsThrow<Derived>::value};
};
template<class Ex>
struct Null : PolicyBase<Null> { };
template<class …Run Code Online (Sandbox Code Playgroud) 我试图有条件地实例化一个额外的赋值运算符.下面的代码在clang中工作正常,但在gcc 4.7中没有.
我遇到的问题似乎与此处提出的问题非常相似:std :: enable_if有条件地编译成员函数
以下说明了我遇到的问题:
#include <type_traits>
template<typename T>
struct StrangerTypeRules;
template<typename T>
struct X;
template< >
struct StrangerTypeRules < unsigned > {
typedef unsigned type;
};
template< >
struct StrangerTypeRules < bool > {
typedef X<bool> type;
};
template<typename T>
struct X {
// In the non-trivial version of my code, I can not use the
// default assignment operator, therefor I need to define this one
X& operator=( const X<T>& rhs ) {
return *this;
} …Run Code Online (Sandbox Code Playgroud) 你将如何在一个std::enable_if?中使用非类型模板参数比较?我无法弄清楚如何再次这样做.(我曾经有过这个工作,但是我丢失了代码,所以我无法回头看看,而且我找不到帖子,我找到了答案.)
提前感谢您对此主题的任何帮助.
template<int Width, int Height, typename T>
class Matrix{
static
typename std::enable_if<Width == Height, Matrix<Width, Height, T>>::type
Identity(){
Matrix ret;
for (int y = 0; y < Width; y++){
elements[y][y] = T(1);
}
return ret;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:修复了注释中指出的缺失括号.
#include <type_traits>
template<bool b>
struct S
{
template<typename = std::enable_if_t<b>>
S() {}
template<typename = std::enable_if_t<!b>>
S(int) {}
};
S<true> s{}; // error in clang/gcc, OK in VC2017
S<false> s{0}; // error in clang/gcc, OK in VC2017
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,clang/gcc尝试实例化由于SFINAE而实际应该丢弃的ctor.错误消息是:
错误:'std :: enable_if <false,void>'中没有名为'type'的类型; 'enable_if'不能用于禁用此声明
clang/gcc对另一个ctor的实例化是不正确的,因为它不应该在可能的重载列表中,对吧?
但在我提交错误之前,我想阅读别人的想法.也许我说得不对劲......
这有什么问题:
#include <type_traits>
struct A;
template<typename T>
struct B
{
template<typename=std::enable_if<std::is_copy_constructible<T>::value>>
void f1() {}
};
template<typename T>
struct C {};
// Type your code here, or load an example.
int main() {
// Following fails
B<A> b;
// Could use this:
// b.f1<C>();
// This complies
C<A> c;
return 0;
}
/* This to be in or not doesn't make a difference
struct A
{};
*/
Run Code Online (Sandbox Code Playgroud)
我在这里尝试过:https : //godbolt.org/z/NkL44s,使用了不同的编译器: