是否存在允许将非const模板实参类型隐式转换为const的规范方法?
Is there a canonical way to allow implicit conversion of a non-const template argument type to a const one?
我有一个函数,它接受特定模板类型的参数;简化的版本可能像这样:
#include <type_traits>
template <typename T>
struct foo
{
// default constructor
foo() { }
// simple copy constructor that can construct a foo<T> from a foo<T>
// or foo<const T>
foo(const foo<typename std::remove_const<T>::type> &) { }
};
功能上,foo
的行为类似于shared_ptr<T>
,具有与此问题无关的其他附加功能。函数的语义决定了它更倾向于接收foo<const T>
。foo<const T>
可以从foo<T>
隐式构造,所以我希望能够做以下事情:
template <typename T>
void bar(foo<const T> f) { }
int main()
{
bar(foo<const int>()); // fine
bar(foo<int>()); // compile error
}
这失败了,因为没有匹配的bar
的重载,foo<int>
(即使foo<const int>
可以隐式地从foo<int>
构造,与模板实例化一致的重载解析似乎比这更严格)。
是否有一个规范的方法来完成这一点?我知道我可以为bar()
引入第二个过载,它接受foo<T>
并手动调度到bar(foo<const T>)
,但如果可能的话,我想避免重复。
模板不允许转换!
当你写:
template <typename T>
void bar(foo<const T> f) { }
bar
接受任何T
的foo<const T>
。它不接受其他任何东西。foo<int>
是否可以转换为foo<const int>
并不重要,因为这种转换从未被考虑过。句号。
如果您想将收到的f
视为const
,您可以有条件地将其设置为const
:
// convert this version
template <class T> foo<T const> make_const_f(foo<T> const& rhs) { return {rhs}; }
// pass this version through
template <class T> foo<T const>& make_const_f(foo<T const>& rhs) { return rhs; }
template <typename T>
void bar(foo<T> f) {
auto&& const_f = make_const_f(f);
// if T was const, const_f is a reference to f
// if T wasn't const, const_f is a new object of type foo<T const>
}
代码不工作的原因是隐式转换在模板参数推导之后应用。因此,在这种情况下,foo<int>
确实与foo<const T>
不匹配,编译器无法推断出T
是什么。你可以自己试着直接检查指定的类型:
int main()
{
bar(foo<const int>()); // fine
bar<int>(foo<int>()); // also fine
}
你能做的是让编译器接受任何类型:
template <typename T> // T might be foo<int>
void bar(T f) { }
或者,如果您愿意,可以让编译器推导出不带const:
的内部T
。template <typename T> // can deduce T as const int
void bar(foo<T> f) { }
如果你真的想执行constness(即使在泛型代码中),你可能想在你的类中添加一个实用函数,就像这样:
foo<const T> as_const() const { return *this; }
所以当你使用泛型函数时,你可以发送const版本的类:
bar<int>(foo<int>{}.as_const());
相关文章:
- 如何在声明为 const 的方法中更改类成员
- 具有参数 (const T *&) 或 (T * &) 或 (const T * const &) 或 (T * const &) 的方法
- 从 const 对象访问非 const 方法
- 为什么我可以调用一个从const方法更改成员的方法
- 使用新的c++返回值语法的Const方法
- MSVC使用constexpr-if从可变模板方法中的基本模板参数中吞下const
- const_cast const 方法中的"this"将"this"分配给外部变量?
- 初始化 const 成员的正确方法
- 为什么 std::unique_ptr 没有 const get 方法
- 为什么使用带有 const 的方法而不是第一个没有常量的方法
- const 类方法是否阻止在类外部分配变量?
- 错误:候选函数不可行:'this'参数具有类型 'const' 但方法未标记为 const
- std::result_of 应用于 const 重载方法
- 当丢失非const虚拟方法时,为什么我不能实例化类的const实例
- const静态方法修改值
- 为什么我不能从 const String& 方法返回 NULL?
- c++中返回引用的重载const和非const类方法
- 与const引用(方法链)相关联的临时对象的生命周期
- 在pass-by-const-reference方法内部的c++ pass-by-non-const-reference
- 我是否应该声明任何可以为const的方法为const方法?