admin管理员组文章数量:1122832
My template needs two types, one that I expect the caller to explicitly specify, the other which should be deducible by the compiler. Yet it requires me to specify it. Commenting out the foo2 line results in a clean build. Is there a way to get the foo2-type variable construction to work?
(The toy example program counts, in a variable of any math type, the number of allocations it makes for you of memory for the explicitly-supplied type.)
#include <cstdlib>
template<class T, class U> class Foo {
public:
Foo( U* counter_in ) : counter( counter_in ) {};
U* counter;
T* Alloc() { *counter += 1; return (T*) malloc( sizeof(T) ); };
};
int iCounter = 0;
Foo<double, int> foo1( &iCounter );
Foo<double> foo2( &iCounter );
int main( int nArg, const char* apszArg[] ) {
double* pd = foo1.Alloc();
return 0;
}
Compiler output:
> g++ -std=c++23 -c -o t.o t.cpp
t.cpp:12:11: error: wrong number of template arguments (1, should be 2)
12 | Foo<double> foo2( &iCounter );
| ^
t.cpp:3:34: note: provided for 'template<class T, class U> class Foo'
3 | template<class T, class U> class Foo {
| ^~~
t.cpp:12:19: error: invalid conversion from 'int*' to 'int' [-fpermissive]
12 | Foo<double> foo2( &iCounter );
| ^~~~~~~~~
| |
| int*
t.cpp: In function 'int main(int, const char**)':
t.cpp:15:18: error: 'foo' was not declared in this scope; did you mean 'Foo'?
15 | double* pd = foo.Alloc();
| ^~~
| Foo
> g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/14/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl= --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-14.0.1-20240411/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.0.1 20240411 (Red Hat 14.0.1-0) (GCC)
My template needs two types, one that I expect the caller to explicitly specify, the other which should be deducible by the compiler. Yet it requires me to specify it. Commenting out the foo2 line results in a clean build. Is there a way to get the foo2-type variable construction to work?
(The toy example program counts, in a variable of any math type, the number of allocations it makes for you of memory for the explicitly-supplied type.)
#include <cstdlib>
template<class T, class U> class Foo {
public:
Foo( U* counter_in ) : counter( counter_in ) {};
U* counter;
T* Alloc() { *counter += 1; return (T*) malloc( sizeof(T) ); };
};
int iCounter = 0;
Foo<double, int> foo1( &iCounter );
Foo<double> foo2( &iCounter );
int main( int nArg, const char* apszArg[] ) {
double* pd = foo1.Alloc();
return 0;
}
Compiler output:
> g++ -std=c++23 -c -o t.o t.cpp
t.cpp:12:11: error: wrong number of template arguments (1, should be 2)
12 | Foo<double> foo2( &iCounter );
| ^
t.cpp:3:34: note: provided for 'template<class T, class U> class Foo'
3 | template<class T, class U> class Foo {
| ^~~
t.cpp:12:19: error: invalid conversion from 'int*' to 'int' [-fpermissive]
12 | Foo<double> foo2( &iCounter );
| ^~~~~~~~~
| |
| int*
t.cpp: In function 'int main(int, const char**)':
t.cpp:15:18: error: 'foo' was not declared in this scope; did you mean 'Foo'?
15 | double* pd = foo.Alloc();
| ^~~
| Foo
> g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/14/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-14.0.1-20240411/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.0.1 20240411 (Red Hat 14.0.1-0) (GCC)
Share
Improve this question
asked Nov 21, 2024 at 18:15
Swiss FrankSwiss Frank
2,4221 gold badge24 silver badges39 bronze badges
1 Answer
Reset to default 2CTAD is a whole or nothing.
You might create a template make_Foo
:
template <typename T, typename U>
Foo <T, U> make_Foo(U* u) { return Foo<T, U>(u); }
and then
auto foo2 = make_Foo<double>( &iCounter );
版权声明:本文标题:c++ - C++2023 class template argument deduction: mix of explicit and deduced template arguments? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736308137a1933554.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论