c++ - 在嵌套模板结构中将引用类型作为模板参数传递不起作用

标签 c++ c++11 templates gcc pass-by-reference

我很困惑,我正在设计一个模板,发现使用 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 的网站。

此外,如果它是一个错误,我会对任何可用的解决方法感兴趣。

最佳答案

变得更加专业。我认为这给出了您想要的行为:

template <typename T>
struct test {
    T get() { return f; }
};

template <typename T>
struct test<T&> {
    const T& get() { return f; }
};

测试:

int main() {      
    const float& f1 = test<float&>().get();
    float& f2 = test<float&>().get(); //Error
    const float& f3 = test<const float&>().get();
    float f4 = std::move(test<float>().get());
}

关于c++ - 在嵌套模板结构中将引用类型作为模板参数传递不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44334530/

相关文章:

c++ - vector::引用

C++ 操作数到标准运算符的隐式转换

c++ - 宏 __TIMESTAMP__ 卡住了

C++ 数组下标运算符模板

c++ - 在 C++ 中如何使用模板调用提供类型的特定成员

c++ - 用于容纳不同类对象的容器

c++ - std::bind 和作用域后堆栈使用

c++ - 忽略函数默认参数

c++ - #include<boost> 没有这样的文件或目录

c++ - 单一定义规则是否强制创建单个静态函数变量?