Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Candidate template ignored: invalid explicitly-specified argument for template parameter #42224

Closed
msimonsson opened this issue Aug 3, 2019 · 6 comments
Labels
bugzilla Issues migrated from bugzilla c++17 clang:frontend Language frontend issues, e.g. anything involving "Sema" duplicate Resolved as duplicate

Comments

@msimonsson
Copy link

msimonsson commented Aug 3, 2019

Bugzilla Link 42879
Version trunk
OS All
CC @DougGregor,@zygoloid

Extended Description

The following code fails to compile with Clang but compiles with GCC (since 7.1). Clang wants a value for the defaulted template parameter Capacity.

#include <cstddef>

template <typename T, size_t Capacity = 10>
class smallvector {
  public:
    smallvector(const T*, size_t);
};

template <typename T>
class span {
  public:
    span(const T*, size_t);
};

class str {
  public:
    str(const char* data, size_t size) : data_{data}, size_{size} {}

    template <template <typename> typename Container>
    Container<const char> to_container() {
        return {data_, size_};
    }

  private:
    const char* data_;
    size_t size_;
};

void to_span(str& s) {
    s.to_container<span>(); // This works.
}

void to_smallvector(str& s) {
    s.to_container<smallvector>(); // This doesn't work.
}
<source>:34:7: error: no matching member function for call to 'to_container'

    s.to_container<smallvector>();

    ~~^~~~~~~~~~~~~~~~~~~~~~~~~

<source>:20:27: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'

    Container<const char> to_container() {

                          ^

1 error generated.

Tested with clang version 10.0.0 (trunk 367740) and -std=c++17.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
@mengyays
Copy link

mengyays commented Apr 3, 2023

the selution: need to redefine the template for original template class:

template<typename T>
using smallvector_T = smallvector<T>;

@EugeneZelenko EugeneZelenko added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Apr 3, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 3, 2023

@llvm/issue-subscribers-clang-frontend

krobelus added a commit to krobelus/kakoune that referenced this issue May 9, 2023
Clang 16 fails to compile calls like "gather<Vector>()".

	c++  -O3 -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -MD -MP -MF .command_manager.opt.d -c -o .command_manager.opt.o command_manager.cc
	command_manager.cc:825:104: error: no matching function for call to 'gather'
	        auto params = tokens | skip(1) | transform(&Token::content) | filter(std::not_fn(is_switch)) | gather<Vector>();
	                                                                                                       ^~~~~~~~~~~~~~
	./ranges.hh:633:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	./ranges.hh:642:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	1 error generated.

because Vector has a defaulted template argument but the argument to
gather() has not.

Upstream bug report: llvm/llvm-project#42224
(not sure why it worked for us with Clang 15).

Work around this by adding gather() overloads whose template template
parameter clang can match against Vector. Add another one for HashSet.

GCC rejects calls to these overloads as ambiguous, so use conditional
compilation.

Fixes mawww#4872
krobelus added a commit to krobelus/kakoune that referenced this issue May 9, 2023
Clang 16 fails to compile calls like "gather<Vector>()".

	c++  -O3 -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -MD -MP -MF .command_manager.opt.d -c -o .command_manager.opt.o command_manager.cc
	command_manager.cc:825:104: error: no matching function for call to 'gather'
	        auto params = tokens | skip(1) | transform(&Token::content) | filter(std::not_fn(is_switch)) | gather<Vector>();
	                                                                                                       ^~~~~~~~~~~~~~
	./ranges.hh:633:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	./ranges.hh:642:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	1 error generated.

because Vector has a defaulted template argument but gather's formal
parameter.

Upstream bug report: llvm/llvm-project#42224
(not sure why it worked for us with Clang 15).

Work around this by adding gather() overloads whose template template
parameter clang can match against Vector. Add another one for HashSet.

GCC rejects calls to these overloads as ambiguous, so use conditional
compilation.

Fixes mawww#4872
krobelus added a commit to krobelus/kakoune that referenced this issue May 9, 2023
Clang 16 fails to compile calls like "gather<Vector>()".

	c++  -O3 -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -MD -MP -MF .command_manager.opt.d -c -o .command_manager.opt.o command_manager.cc
	command_manager.cc:825:104: error: no matching function for call to 'gather'
	        auto params = tokens | skip(1) | transform(&Token::content) | filter(std::not_fn(is_switch)) | gather<Vector>();
	                                                                                                       ^~~~~~~~~~~~~~
	./ranges.hh:633:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	./ranges.hh:642:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	1 error generated.

because Vector has a defaulted template argument but gather's formal
parameter.

Upstream bug report: llvm/llvm-project#42224
(not sure why it worked for us with Clang 15).

Work around this by adding gather() overloads whose template template
parameter clang can match against Vector. Add another one for HashSet.

GCC rejects calls to these overloads as ambiguous, so use conditional
compilation.

Fixes mawww#4872
krobelus added a commit to krobelus/kakoune that referenced this issue May 19, 2023
…mplate template args

Clang 16 fails to compile calls like "gather<Vector>()".

	c++  -O3 -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -MD -MP -MF .command_manager.opt.d -c -o .command_manager.opt.o command_manager.cc
	command_manager.cc:825:104: error: no matching function for call to 'gather'
	        auto params = tokens | skip(1) | transform(&Token::content) | filter(std::not_fn(is_switch)) | gather<Vector>();
	                                                                                                       ^~~~~~~~~~~~~~
	./ranges.hh:633:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	./ranges.hh:642:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	1 error generated.

because Vector has a defaulted template argument but gather's formal
parameter.

Upstream bug report: llvm/llvm-project#42224
(not sure why it worked for us with Clang 15).

Work around this by adding gather() overloads whose template template
parameter clang can match against Vector. Add another one for HashSet.

GCC rejects calls to these overloads as ambiguous, so use conditional
compilation.

Fixes mawww#4872
@jdoubleu
Copy link

I found this one interesting: https://godbolt.org/z/P3fno44o1
I'm not sure who's right and who's wrong. Maybe gcc just accepts it, because of the class template's (i.e. std::map) default parameters.

The solution is to either match the template's parameter count or use a template pack:

template<template<typename...> typename C>

@cor3ntin
Copy link
Contributor

@jdoubleu I think this is just clang not implementing C++17 template template argument matching rules by default. The GCC/conforming behavior can be subscribed to by passing -frelaxed-template-template-args. @mizvekov

@mizvekov
Copy link
Contributor

Duplicate of #36505

@mizvekov mizvekov marked this as a duplicate of #36505 Apr 28, 2024
@mizvekov mizvekov closed this as not planned Won't fix, can't repro, duplicate, stale Apr 28, 2024
@EugeneZelenko EugeneZelenko added the duplicate Resolved as duplicate label Apr 28, 2024
@Endilll Endilll added c++17 and removed c++ labels Apr 28, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 28, 2024

@llvm/issue-subscribers-c-17

Author: Mikael Simonsson (msimonsson)

| | | | --- | --- | | Bugzilla Link | [42879](https://llvm.org/bz42879) | | Version | trunk | | OS | All | | CC | @DougGregor,@zygoloid |

Extended Description

The following code fails to compile with Clang but compiles with GCC (since 7.1). Clang wants a value for the defaulted template parameter Capacity.

#include &lt;cstddef&gt;

template &lt;typename T, size_t Capacity = 10&gt;
class smallvector {
  public:
    smallvector(const T*, size_t);
};

template &lt;typename T&gt;
class span {
  public:
    span(const T*, size_t);
};

class str {
  public:
    str(const char* data, size_t size) : data_{data}, size_{size} {}

    template &lt;template &lt;typename&gt; typename Container&gt;
    Container&lt;const char&gt; to_container() {
        return {data_, size_};
    }

  private:
    const char* data_;
    size_t size_;
};

void to_span(str&amp; s) {
    s.to_container&lt;span&gt;(); // This works.
}

void to_smallvector(str&amp; s) {
    s.to_container&lt;smallvector&gt;(); // This doesn't work.
}
&lt;source&gt;:34:7: error: no matching member function for call to 'to_container'

    s.to_container&lt;smallvector&gt;();

    ~~^~~~~~~~~~~~~~~~~~~~~~~~~

&lt;source&gt;:20:27: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'

    Container&lt;const char&gt; to_container() {

                          ^

1 error generated.

Tested with clang version 10.0.0 (trunk 367740) and -std=c++17.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++17 clang:frontend Language frontend issues, e.g. anything involving "Sema" duplicate Resolved as duplicate
Projects
None yet
Development

No branches or pull requests

8 participants