是一个模板化的函数,它支持C++ 11中不同级别的间接?

Com*_*bot 3 c++ templates generic-programming c-preprocessor c++11

基本上,我很好奇你是否可以使用C++ 11模板来实现它,因此模板化函数可以检测迭代器的间接级别,并根据不同的方式编译函数.例如,以下是一些无法编译的代码:

#include <vector>
#include <list>
#include <type_traits>
#include <iostream>

struct MyStruct
{
  int value;
  MyStruct(int value = 42) : value(value) { }
  const int& getInt() const { return value; }
};

typedef std::list<MyStruct> StructList;
typedef std::vector<const MyStruct*> StructPtrVector;

template <typename ITER_TYPE>
const int& getIteratorInt(ITER_TYPE iter)
{
  if (std::is_pointer<decltype(*iter)>::value)
    return (*iter)->getInt(); // Won't compile -> MyStruct has no operator-> defined
  return iter->getInt(); // Won't compile -> MyStruct* has the wrong level of indirection
}

template <typename LIST_TYPE>
void PrintInts(const LIST_TYPE& intList)
{
  for (auto iter = intList.begin(); iter != intList.end(); ++iter)
    std::cout << getIteratorInt(iter) << std::endl;
}

int main(void)
{
  StructList structList;
  StructPtrVector structPtrs;
  int values[5] = { 1, 4, 6, 4, 1 };
  for (unsigned i = 0; i < 5; ++i)
  {
    structList.push_back(values[i]);
    structPtrs.push_back(&structList.back());
  }
  PrintInts(structList);
  PrintInts(structPtrs);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

显而易见的情况是,您有一个对象列表,然后是一个不同类型的对象指针列表.并且,您想要做的是两个列表相同,将它们视为对象列表.

上面的代码不会编译,因为它正在进行逻辑检查,应该在编译时完成.我不知道是否有办法用预处理器宏来做到这一点.我试过一个简单的#if std::is_pointer<decltype(*iter)>::value == true,但编译器似乎总是认为它是假的.(我以前从未尝试过预处理器宏,但这显然不是正确的方法.)

有没有想过它是否可能?

Pot*_*ter 7

当你想在两个实现之间进行选择时,取决于一个元函数,例如is_pointer,使用std::enable_if,这是根据SFINAE的原理工作的.

template <typename ITER_TYPE>
auto getIteratorInt(ITER_TYPE iter) ->
typename std::enable_if< std::is_pointer< 
        typename std::iterator_traits< ITER_TYPE >::value_type >::value,
    const int& >::type
{
  return (*iter)->getInt();
}

template <typename ITER_TYPE>
auto getIteratorInt(ITER_TYPE iter) ->
typename std::enable_if< ! std::is_pointer< 
        typename std::iterator_traits< ITER_TYPE >::value_type >::value,
    const int& >::type
{
  return iter->getInt();
}
Run Code Online (Sandbox Code Playgroud)

这样,模板实例化只能看到对给定模板参数有效的代码行.

我刚刚在机制上将这个修复程序应用于你的代码......我并不是主张使用多个间接或建议固定的实现是健壮的.