我想要做的是定义如下3个函数:
template<int t = 0> int test() { return 8; }
template<int t = 1> float test() { return 8.8; }
template<int t = 2> std::string test() { return "8.9"; }
int main()
{
int a = test<0>();
float b = test<1>();
std::string c = test<2>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它们使用相同类型的模板参数,但返回不同类型。
我相信一定有某种方法可以做到这一点(就像这样 std::get<>()
做),但是我找不到如何做到这一点。
前向声明的模板变量会导致 ld 错误。
#include <iostream>
template<class T> extern int a;
template<class T> int a = 1;
int main()
{
std::cout << a<int> << a<float>;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ LANG=C g++ main.cpp -o main
/usr/bin/ld: /tmp/cccOb25F.o: in function `main':
main.cpp:(.text+0x6): undefined reference to `a<int>'
/usr/bin/ld: main.cpp:(.text+0x1d): undefined reference to `a<float>'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
但是,前向声明变量(无模板)和前向声明模板函数工作正常。
#include <iostream>
extern int a;
int a = 1;
template<class T> int b();
template<class T> int b()
{
return 2;
}
int main() …
Run Code Online (Sandbox Code Playgroud) 我只是stringstream
在UTF-8中尝试:
#include<iostream>
#include<string>
#include<sstream>
int main()
{
std::basic_stringstream<char8_t> ss(u8"hello");
char8_t c;
std::cout << (ss.rdstate() & std::ios_base::goodbit) << " " << (ss.rdstate() & std::ios_base::badbit) << " "
<< (ss.rdstate() & std::ios_base::failbit) << " " << (ss.rdstate() & std::ios_base::eofbit) << "\n";
ss >> c;
std::cout << (ss.rdstate() & std::ios_base::goodbit) << " " << (ss.rdstate() & std::ios_base::badbit) << " "
<< (ss.rdstate() & std::ios_base::failbit) << " " << (ss.rdstate() & std::ios_base::eofbit) << "\n";
std::cout << c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译使用:
g++-9 …
Run Code Online (Sandbox Code Playgroud) 我想写一个类模板,其中:
A<float>
只有一个成员变量val
;A<int>
有一个成员变量val
和一个成员函数make_unsigned
(返回unsigned
)。我想明确说明make_unsigned
. 这是我的代码。
#include <concepts>
template<typename T> struct A
{
T val;
std::make_unsigned_t<T> make_unsigned() requires std::signed_integral<T>
{
return static_cast<std::make_unsigned<T>::type>(val);
}
};
int main()
{
A<float> val;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我也试过auto make_unsigned() requires std::signed_integral<T> -> std::make_unsigned_t<T>
and auto make_unsigned() -> std::make_unsigned_t<T> requires std::signed_integral<T>
,但都不能编译。它抱怨:
~ LANG=C g++ main.cpp -std=c++20 -o main
In file included from /usr/include/c++/10.2.0/bits/move.h:57,
from /usr/include/c++/10.2.0/bits/stl_pair.h:59,
from /usr/include/c++/10.2.0/utility:70,
from /usr/include/c++/10.2.0/array:38,
from main.cpp:1:
/usr/include/c++/10.2.0/type_traits: In …
Run Code Online (Sandbox Code Playgroud) 仅头文件库中的函数应声明为inline
防止不同翻译单元中的多个定义。也就是说,例如,我编写了一个仅包含头文件的库mylib.hpp
:
void do_something(int) {}\n
Run Code Online (Sandbox Code Playgroud)\n我在两个不同的 cpp 文件中使用了这个标头:
\n// a.cpp\n# include "mylib.hpp"\nvoid func1() {do_something(1);}\n
Run Code Online (Sandbox Code Playgroud)\n// b.cpp\n# include "mylib.hpp"\nvoid func2() {do_something(2);}\n
Run Code Online (Sandbox Code Playgroud)\n使用 构建它们g++ -o main a.cpp b.cpp
,GCC 会抱怨“多重定义do_something(int)
”。为了防止这种情况,定义函数,static void do_something(int) {}
使其在每个翻译单元中都有一个副本(即,在最后的输出中有两个副本),或者定义函数,如inline void do_something(int) {}
使其在最后的输出中只有一个副本,这就是我们想要。
但是,如果我想强制do_something
不被编译器内联(例如,我想使用 backtrace 库来动态查找调用了哪个函数do_something
),我应该这样写:
[[gnu::noinline]] inline void do_something(int) {}\n
Run Code Online (Sandbox Code Playgroud)\n然而,海湾合作委员会抱怨:
\nWarning: inline declaration of \xe2\x80\x98do_something(int)\xe2\x80\x99 follows declaration with attribute \xe2\x80\x98noinline\xe2\x80\x99 [-Wattributes]\n
Run Code Online (Sandbox Code Playgroud)\n那么,做这些事情的正确方法是什么?
\n假设我们有一个consteval
函数或一个带有consteval
构造函数的简单结构,它只接受一些值:
struct A
{
consteval A(int a)
{
// compile error if a < 0
if (a < 0)
throw "error";
}
};
Run Code Online (Sandbox Code Playgroud)
有什么方法可以检测这样的构造函数是否可以接受 int 的非类型模板参数?我尝试过以下代码但失败了。
template <int a> concept accepted_by_A = requires() {A(a);};
int main()
{
std::cout << accepted_by_A<-1> << std::endl; // output 1 (true)
}
Run Code Online (Sandbox Code Playgroud) c++ ×6
c++20 ×2
templates ×2
c++-concepts ×1
consteval ×1
gcc ×1
gcc9 ×1
header-only ×1
return-type ×1