重新排序重载的模板功能

时间:2018-06-19 10:03:24

标签: c++ templates c++14 template-meta-programming

我有一个使用外部函数InsertStatement的课程bind

namespace sqlite {

template <typename T>
inline void bind(SQLiteStatement &statement, size_t idx, const T &value) {
    statement.bind(idx, value);
}

template<typename ...FIELDS>
class InsertStatement {

   ...
   template <typename T>
   bool bindValue(int idx, const T& t) {
       sqlite::bind(*statement, idx+1, t);
       return true;
   }
   ...
};

使用外部函数的原因是能够覆盖它并支持InsertStatement类中其他类型的使用。例如,如果我想将其与StrongType<T>一起使用,我可以这样做:

template <typename T, typename TAG>
class StrongType {
private:
    T value;
public:
    StrongType (T&& v)
            : value(std::forward<T>(v)) {

    }

    T toValue() const
    {
        return value;
    }
};

namespace sqlite {

template <typename T, typename TAG>
inline void bind (SQLiteStatement &statement, size_t s, const StrongType<T,TAG> &strongType) {
    statement.bind(s, strongType.toValue());
}
}

问题是我需要在 StrongType.h之前包含InsertStatement.h ,否则编译器无法正确解析函数调用。

虽然我可以直观地解释,但问题是,我该如何避免这个问题呢?我不希望来自#include "StrongType.h" InsertStatement.h,因为StrongType是一个与此库没有直接关系的外部类,因为这确实会出现在任何新类型中,我想保留这个班足够灵活。

我正在使用不同的编译器(gcc,clang和MSVC),c ++ 14(c ++ 17或更高版本目前不是一个选项)。

  1. 如何避免这种“标题排序”问题?
  2. 使用其他类型扩展Templated类的最佳方法是什么,其类型的详细信息是未知的?

1 个答案:

答案 0 :(得分:1)

您可能依赖ADL并且bind位于与StrongType相同的命名空间中。
(你不需要使用合格的电话):

template <typename T>
bool bindValue(int idx, const T& t) {
    using sqlite::bind;
    bind(*statement, idx+1, t);
    return true;
}