【发布时间】:2014-07-25 18:59:12
【问题描述】:
我的实际用例需要更多参数,但它简化为:
template< typename Arg1 >
bool algorithm( Arg1&& p1, **p2 here** );
很明显,Arg1 将以某种方式崩溃并可能成为某种参考。 p1 也是算法的输出,因此如果调用者选择传入一个左值,函数将返回并修改原始参数以反映它停止的位置。
但是 p2 是同一类型但永远不会被修改。所以实际上我想在那里放一个'const'承诺以确保正确性。显然,如果 Arg1 推断为引用,我不能将 const 添加到它。
所以我的解决方案是这样的:
template< class T >
struct make_const_ref
{
typedef typename std::add_reference< typename std::add_const< typename std::remove_reference< T >::type >::type >::type type;
};
template< typename Arg1 >
bool algorithm( Arg1&& p1, typename make_const_ref<Arg1>::type p2 );
它通过一堆愚蠢的阴谋来删除一些限定符,然后重新粘贴 const&。
所以我的问题是:
1) 这是最好的方法吗?
2) 是否存在会失败的上下文?现在我觉得还不错。
【问题讨论】:
-
typedef typename std::add_reference< typename std::add_const< typename std::remove_reference< T >::type >::type >::type type;嗯,为什么不只是using type = typename std::remove_reference<T>::type const&;? -
"p1 也是算法的输出,因此如果调用者选择传入左值,函数将返回原始参数,修改后的参数以反映它停止的位置。" 退货不是一种选择吗?通常,返回更简洁,因为它不会产生副作用(使用元组返回多个值)。
-
"但是 p2 是同一类型,但永远不会被修改。" 它是否需要是相同的 i> 类型?您还可以使用另一个模板参数加上
static_assert或 SFINAE 检查它是否必须是 same 类型。 -
@dyp 其实我可以使用模板别名。直到最近我们还在 VS2012 上,所以它只是让我忘记了。谢谢 - 它使它更整洁。
-
是的,但请注意,类型特征和其他类型函数(元函数)通常/按照约定是具有嵌套 typedef
type的类 (struct)。为方便起见,您可以提供 additional 别名模板,但为了更好的可重用性,我会坚持使用 Trait 的约定。
标签: c++ templates reference constants universal-reference