从类模板中排除转换运算符... <typename t =“”>基于T

时间:2018-02-20 16:32:49

标签: c++ templates language-lawyer c++03

此问题涵盖 C ++ 03 ,以及如何在template<typename T> struct Foo { ... };给出特征时,从类模板中省略转换运算符,例如T

(底部的问题)

背景

理想情况下,我希望使用enable_if构造和SFINAE根据类模板T的特征排除转换运算符(请参阅上面的Foo),但是在C ++ 03中的函数模板中可能没有使用默认模板参数,(afaik)排除了这种方法;如先前在以下主题中所述:

相反,我正在使用一种方法,其中转换运算符的返回值的类型取决于T上的特征,特别是虚拟(void或某些私有外部不可访问类型)对于某些类型的T。这种方法似乎工作正常,但我不确定我可能会为自己挖掘什么可能的陷阱;特别是在这种情况下(C ++ 03)标准所保证的。

使用前一段中描述的方法,考虑以下示例(我尽可能保持尽可能小):

include/util.h

namespace util {

// dummy predicate: is T int?
template <typename T> struct is_int { static const bool value = false; };
template <> struct is_int<int> { static const bool value = true; };
template <typename T> const bool is_int<T>::value;

// [meta.trans.other]/conditional
template <bool B, class T, class F> struct conditional { typedef T type; };
template <class T, class F> struct conditional<false, T, F> { typedef F type; };

// class template with non-template operator() member
template <typename T> struct Foo {
    explicit Foo(const T &value) : value_(value) {}

    // [Question regarding this conversion operator here]
    operator typename conditional<is_int<T>::value, int, void>::type() const {
        return value_;
  }

private:
  T value_;
};

/* Alternatively */
template <typename T> class Bar {
    struct Dummy {};
    T value_;
public:
    explicit Bar(const T &value) : value_(value) {}
    operator typename conditional<is_int<T>::value, int, Dummy>::type() const {
        return value_;
  }
};

}  // namespace util

main.cc

#include "include/util.h"

void baz(int) {}

int main()
{
    const util::Foo<int> foo_int(42);
    baz(foo_int); // OK
    const util::Foo<char> foo_char('a');

    const util::Bar<int> bar_int(42);
    baz(bar_int); // OK
    const util::Bar<char> bar_char('a');

    /* OK, expected:
       Error: cannot convert ‘const util::Foo<char>’/‘const util::Bar<char>’
         to ‘int’ for argument ‘1’ to ‘void baz(int)
    baz(foo_char);
    baz(bar_char); */

    return 0;
}

这可以使用gccclang-std=c++03)进行编译,但我想知道转换运算符是否有条件地存在无效正文(/ return)是否正常,就像这样的情况对于Foo<char>的完整实例化。由于部分隐式实例化,我认为它很好; [temp.inst] / 1(14.7.1 in the C++03 standard draft)描述了[强调我的]:

  

类模板特化的隐式实例化导致   声明的隐式实例化,但不是   定义或默认参数,类成员函数的 ,   成员类,静态数据成员和成员模板;而且它   导致成员定义的隐式实例化   匿名工会。除非类模板的成员或成员   模板已被显式实例化或明确专门化,   成员的特化是隐式实例化的当   在需要成员的上下文中引用特化   存在的定义;

问题

  • C ++ 03标准是否保证类模板的有条件(T)无效的非模板成员函数体不是错误,以防它未从类的实例化中引用它会/无效吗?

0 个答案:

没有答案