Meu programa se comporta como eu espero no modo C++20 do Visual Studio, mas preciso fazê-lo rodar no modo C++17, onde o programa altera sua saída.
Após a minimização, fica assim:
template <typename T>
int f() { return g(T{}); }
namespace {
struct A{
friend int g(const A &) { return 1; }
};
}
template <typename T>
int g(T&&) { return 2; }
int main() { return f<A>(); }
No modo C++20 a saída de main()
é 1
, enquanto no modo C++17 a saída é 2
. Demonstração online: https://gcc.godbolt.org/z/h8b8qoGGj
Gostaria de saber qual novo recurso do C++20 (ausente no C++17) é responsável pela discrepância do resultado.
Não tem nada a ver com C++17 vs C++20.
O comportamento de pesquisa de nome padrão do MSVC em modelos não está em conformidade com o padrão. Você precisa fornecer o
/permissive-
sinalizador para que ele esteja em conformidade com o padrão.O
/std:c++20
sinalizador (ou qualquer/std:c++*
sinalizador para uma revisão mais recente do C++)/permissive-
também define implicitamente, enquanto/std:c++17
os sinalizadores e para revisões anteriores não.No C++ padrão, o resultado
1
sempre foi a única resposta correta. A segunda sobrecarga deg
não pode ser encontrada pela pesquisa não qualificada usual para a chamada emf
porque essa pesquisa é realizada a partirf
do ponto de definição de onde a sobrecarga ainda não foi declarada. Ela também não pode ser encontrada pelo ADL, porque não é colocada no mesmo namespace queA
.