gpt4 book ai didi

c++ - 类模板的条件无效成员函数(隐式实例化有效;显式实例化失败)

转载 作者:行者123 更新时间:2023-11-28 01:25:57 26 4
gpt4 key购买 nike

我创建了一个类模板。根据其模板参数,它支持不同的操作。类模板应(隐式)实例化为模板参数的几种组合。对于其中一些组合,可能存在没有意义的成员函数(也无法编译)。然而,只要我不强制执行显式实例化,一切似乎都按预期工作。

现在,有这些可怕的案例,称为“未指定”、“未定义”、“格式错误;无需诊断”……。我绝对想避免任何这些事情。所以我想寻求如何处理这种情况的建议。

这是一个显示相同观察结果的示例。请注意,我对如何修复这个确切的玩具示例不太感兴趣。

#include <iostream>
#include <type_traits>

template<class T>
struct SingleSink {
SingleSink(T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};

template<class T>
struct DoubleSink {
DoubleSink(T, T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};

template<class T, int arity /*, some other stuff */>
struct SuperSink {
// This class shall do something special depending on, say, `arity`.
// Instead of partially specializing the whole class template (and introducing
// code duplication for the remaining functionality), let us externalize the
// `arity`-dependent behavior to a special member.

using Sink = std::conditional_t<
arity == 1,
SingleSink<T>,
DoubleSink<T>
>;

Sink sink_;

// [some more data members that do not depend on `arity`]

// for a fixed `Sink` one of the following constructors should fail to compile
SuperSink(T i) : sink_{i} {}
SuperSink(T i, T j) : sink_{i, j} {}
// ... so these are what I call "conditionally invalid member functions".
};

// explicit instantiation yields error (deactivated by comments):
// template struct SuperSink<int, 1>;
// template struct SuperSink<int, 2>;

int main() {
// implicit instantiation works
SuperSink<int, 1>{5};
SuperSink<int, 2>{5, 6};

// these yield a compile error (as desired)
// SuperSink<int, 1>{5, 6};
// SuperSink<int, 2>{5};
}
  1. 如果我从不需要显式实例化?
  2. 如果是:检查显式实例化是否有效是一种好的做法吗?

最佳答案

Are these conditionally invalid member functions a problem if I never need explicit instantiation?

即使是来自 STL 的模板也有“无效”的方法,例如:std::vector<T>::resize(std::size_t)使用非默认构造 T .

因此,对于“无效”方法,您的类可以正常使用。记录您的要求是一种选择。

但是,这些方法对 SFINAE 不友好,因为错误不会出现在直接上下文中,而是出现在实例中。

您可以自己使用 SFINAE 在无效时删除它们,例如:

template <std::size_t N = arity, std::enable_if_t<N == 1, int> = 0>
SuperSink(T i) : sink_{i} {}

template <std::size_t N = arity, std::enable_if_t<N != 1, int> = 0>
SuperSink(T i, T j) : sink_{i, j} {}

在 C++2a 中,您可以指定一些条件以在类中包含方法(与上面的 SFINAE 类似,但具有更好的语法并且没有额外的模板):

SuperSink(T i) requires (arity == 1) : sink_{i} {}

SuperSink(T i, T j) requires (arity != 1) : sink_{i, j} {}

关于c++ - 类模板的条件无效成员函数(隐式实例化有效;显式实例化失败),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53857298/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com