简体   繁体   中英

C++ Wconversion warning in constexp functions but not in templates

My question is why the following code generates warning only for constexpr functions but not for templates?

I do understand what warnings mean and how to get rid of them. What I do not understand is why a compiler do not produce warnings for constexpr members ToDouble and ToSquare of a struct Test below?

#include <iostream>

template <typename T, T value>
struct Test {
  static constexpr double ToDouble = value;

  static constexpr T ToSquare = value * value;
};

template <typename T>
constexpr double ToDouble(T value) {
  return value;
}

template <typename T>
constexpr T ToSquare(T value) {
  return value * value;
}

int main() {
  std::cout << Test<long, 1>::ToDouble << std::endl;
  std::cout << ToDouble(static_cast<long>(1)) << std::endl;

  std::cout << Test<char, 1>::ToSquare << std::endl;
  std::cout << ToSquare(static_cast<char>(1)) << std::endl; 
}
$ g++ -Wconversion -std=c++11 a.cc 
a.cc: In instantiation of ‘constexpr double ToDouble(T) [with T = long int]’:
a.cc:22:45:   required from here
a.cc:12:10: warning: conversion to ‘double’ from ‘long int’ may alter its value [-Wconversion]
   return value;
      ^~~~~
a.cc: In instantiation of ‘constexpr T ToSquare(T) [with T = char]’:
a.cc:25:45:   required from here
a.cc:17:16: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
   return value * value;

The template generates a type. In each instance of the type the value value is a compile time constant. And it can check for loss of precision.

The constexpr case, the template function's generated functions do not have this property. The argument value is not guaranteed to be a compile time constant. While you only use it in a context where it is a compile time constant, the warning doesn't examine every calling context.

Possibly you misunderstand constexpr ; on functions it states the function can be compile time evaluated, not that it must be .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM