非类型模板参数
Non type template parameter
考虑一下:
#include <set>
template <typename T, T val>
class sample {
public:
// Return val for new elements.
T& at(unsigned i) {
auto o = _set.insert(val);
return *o.first;
}
private:
std::set<T> _set;
};
class s {
public:
constexpr s() = default;
};
int main() {
constexpr s val;
sample<s, val> o2;
return 0;
}
gcc -std=c++11 无法编译。
non-type.cc: In function ‘int main()’:
non-type.cc:24:18: error: ‘class s’ is not a valid type for a template non-type parameter
sample<s, val> o2;
如评论中所述,我希望 'set' 的新元素初始化为 'val'。由于 val 是常量,看起来合理的预期!
有人可以告诉我如何实现吗?
看起来你想做的事是可行的,但需要 C++20。
来自docs
在 C++20 之前,"non-type parameter" 必须是
之一
- std::nullptr_t (since C++11);
- an integral type;
- a pointer type (to object or to function);
- a pointer to member type (to member object or to member function);
- an enumeration type.
目前似乎无法使用自定义类型的非类型参数,除非您可以访问已经具有该功能的编译器。
您示例中的解决方法是接受引用。即使在 C++11 中,对静态对象的引用也是有效的非类型模板参数。
template <typename T, T const & val>
class sample {
// ...
};
// ...
constexpr static s val;
sample<s, val> o2;
由于您打算使用 constexpr
val,因此将其设为 static
似乎也合适。
考虑一下:
#include <set>
template <typename T, T val>
class sample {
public:
// Return val for new elements.
T& at(unsigned i) {
auto o = _set.insert(val);
return *o.first;
}
private:
std::set<T> _set;
};
class s {
public:
constexpr s() = default;
};
int main() {
constexpr s val;
sample<s, val> o2;
return 0;
}
gcc -std=c++11 无法编译。
non-type.cc: In function ‘int main()’:
non-type.cc:24:18: error: ‘class s’ is not a valid type for a template non-type parameter
sample<s, val> o2;
如评论中所述,我希望 'set' 的新元素初始化为 'val'。由于 val 是常量,看起来合理的预期!
有人可以告诉我如何实现吗?
看起来你想做的事是可行的,但需要 C++20。
来自docs
在 C++20 之前,"non-type parameter" 必须是
之一- std::nullptr_t (since C++11); - an integral type; - a pointer type (to object or to function); - a pointer to member type (to member object or to member function); - an enumeration type.
目前似乎无法使用自定义类型的非类型参数,除非您可以访问已经具有该功能的编译器。
您示例中的解决方法是接受引用。即使在 C++11 中,对静态对象的引用也是有效的非类型模板参数。
template <typename T, T const & val>
class sample {
// ...
};
// ...
constexpr static s val;
sample<s, val> o2;
由于您打算使用 constexpr
val,因此将其设为 static
似乎也合适。