【发布时间】:2017-11-04 04:41:51
【问题描述】:
我很困惑,我正在设计一个模板,我发现使用T=float& 实例化模板时出现奇怪的行为:
// Given an available float f:
float f = 1.0;
// This getter works for T=float&:
template <typename T>
struct test {
const T get() { return f; }
};
int main() {
float& f1 = test<float&>().get();
}
第一个奇怪的事情是 f1 应该是 const float& 代码是正确的,因此,我预计会出现错误,但它工作正常。
第二个奇怪的事情是在这个类似的例子中,当我不希望它报告错误时:
// Given an available float f:
float f = 1.0;
struct State {
const float& get() { return f; }
};
// This does not work for T=float&:
template <typename T>
struct test2 {
State state;
const T get() { return state.get(); }
};
int main() {
const float& f2 = test2<float&>().get();
}
报错是这样的:
main.cpp: In instantiation of 'const T test2<T>::get() [with T = float&]':
main.cpp:31:41: required from here
main.cpp:22:36: error: binding reference of type 'float&' to 'const float' discards qualifiers
const T get() { return state.get(); }
这很奇怪,因为第二个例子只声明了const float&类型,而不是float&而不是const float,所以我不知道发生了什么。
也许模板不是为使用引用而设计的,或者它是 GCC 上的一个错误,或者我只是在做一些愚蠢的事情。
我使用gcc (GCC) 6.3.1 20170306 和repl.it 网站上使用C++11 测试了这段代码。
另外,如果它是一个错误,我会对任何可用的解决方法感兴趣。
【问题讨论】:
-
实际上我不希望得到
const float&,因为那是对 const float 的引用。当您将T=float&替换为const T时,您会得到const (float&),但我认为您实际上不能形成 const 引用(不同于对 const 的引用) -
嗯,有道理。所以不可能通过使用
T=float&来使函数返回const float&?有没有办法模拟这种行为?对于我的模板的用户来说,让它有时返回float有时返回float&是有意义的。另一种方法是创建一个具有不同名称的第二个模板来涵盖这两种情况。 -
const typename std::remove_reference<T>::type&,也许 -
嗯,这是一个不错的技巧,但用户将无法通过传递
T=float使函数仅返回const float。毕竟我可能最终会为这个案例编写第二个模板。
标签: c++ c++11 templates gcc pass-by-reference