此问题涵盖 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;
}
这可以使用gcc
和clang
(-std=c++03
)进行编译,但我想知道转换运算符是否有条件地存在无效正文(/ return)是否正常,就像这样的情况对于Foo<char>
的完整实例化。由于部分隐式实例化,我认为它很好; [temp.inst] / 1(14.7.1 in the C++03 standard draft)描述了[强调我的]:
类模板特化的隐式实例化导致 声明的隐式实例化,但不是 定义或默认参数,类成员函数的 , 成员类,静态数据成员和成员模板;而且它 导致成员定义的隐式实例化 匿名工会。除非类模板的成员或成员 模板已被显式实例化或明确专门化, 成员的特化是隐式实例化的当 在需要成员的上下文中引用特化 存在的定义;
问题
T
)无效的非模板成员函数体不是错误,以防它未从类的实例化中引用它会/无效吗?